简体   繁体   中英

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

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 :

interface test {
   ____ get();
}

class A extends test {
  int val;

  A(int x) {
    val = x;
  }

  int get() {
    return Val;
  } 


  class B extends test {
  String val;

  B(String x) {
    val = x;
  }

  String get() {
    return Val;
  } 

Is it possible to have a method signature that is able to return two different data types?

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.

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM