Interface (two methods, different return types depending on class) Java

前端 未结 4 1187
甜味超标
甜味超标 2021-01-18 17:49

Any class that extends an interface must implement the methods declared in the interface. Not sure if this is possible but what I want to do is the following :



        
相关标签:
4条回答
  • 2021-01-18 18:30

    No, it's not possible. The interface serves as a "binding contact" of the signatures that are available.

    If you want you can have the function return an Object and by that allow different implementations to return values of different types, but:

    1. It must be references, not primitives.
    2. You loose type safety at the call site.
    0 讨论(0)
  • 2021-01-18 18:40

    This compiles, although I'm not sure I recommend doing things this way:

    interface test {
       Object get();
    }
    
    class A implements test {
      int val;
    
      public A(int x) {
        val = x;
      }
    
      public Integer get() {
        return val;
      } 
    }
    
    class B implements test {
      String val;
    
      public B(String x) {
        val = x;
      }
    
      public String get() {
        return val;
      } 
    }
    

    It's legal in Java to override a method using a return type that is a subclass of the original method's return type. This is called "covariance". It only works on return types, not on parameters. Note that to get this to compile, I had to make get in class A return Integer and not int. Also: use implements, not extends, when implementing an interface; and make sure that you use the correct letter case when referring to variables (Val in your posted code does not work).

    As I said, I'm not sure I recommend this, because in any code that declares something of type test, the result of get() is an Object, which you will have to cast to something else to make it useful. If possible, generics should be used instead. However, it's not always possible. I would think carefully about your design before writing an interface like this. It may be that an interface isn't really what you want. However, I can't tell without more details about what you're trying to accomplish.

    0 讨论(0)
  • 2021-01-18 18:47

    Not exactly like that but you can get close with a generic type parameter.

    interface Test<T> {
        T get();
    }
    
    class A implements Test<Integer> {
        int val;
    
        A(int x) {
            val = x;
        }
    
        @Override
        public Integer get() {
            return val;
        }
    }
    
    class B implements Test<String> {
        String val;
    
        B(String x) {
            val = x;
        }
    
        @Override
        public String get() {
            return val;
        }
    }
    

    As you can see, you're bound to use Integer because generics don't work with primitives.

    Also note, those 2 versions of the same interface are essentially 2 different interfaces now.

    0 讨论(0)
  • 2021-01-18 18:54

    You can do this with generics, but it's not enforced at runtime. You should also be using implements to implement an interface in a class, rather than extends.

    interface Test<T> {
       T get();
    }
    
    class A implements Test<Integer> {
        int val;
    
        A(int x) {
            val = x;
        }
    
        @Override
        Integer get() {
           return Val;
        } 
    
    }
    
    class B implements Test<String> {
        String val;
    
        B(String x) {
           val = x;
        }
    
        @Override
        String get() {
            return Val;
        }
    }
    

    Generics only apply to classes, so you're forced to use Integer rather than int as the return type.

    0 讨论(0)
提交回复
热议问题