【问题标题】:Methods with the same signature but different return type in two interfaces两个接口中签名相同但返回类型不同的方法
【发布时间】:2018-09-08 19:40:53
【问题描述】:

我有两个接口:

interface S {
    public String m1();
}

interface O {
    public Object m1();
}

我决定在一个类 Test 中同时实现 O 和 S :

class Test implements O, S {

}

我的问题:

为什么我必须只实现 public String m1() 方法而不是其他方法? 其次,为什么我不能实现public Object m1() 而不是public String m1()

【问题讨论】:

  • 我找到了一个可能有帮助的答案。 stackoverflow.com/questions/1882584/…
  • 一个接口就是一个promise。返回String 实现了返回Object 的承诺,但反之则不然。
  • 假设您的测试被允许实现public Object get(){...},并且在该方法中您return new Person("Adam"); }(Person 扩展了 Object,因此它是这种方法的可接受结果)。现在想象在其他地方有像method(S s){ String value = s.get(); } 这样的方法。所以它需要S,所以我们可以传递Test实例,因为它实现了S。但是在String value = s.get(); 而不是预期的String 我们得到了Person。这样可以吗?

标签: java


【解决方案1】:

Java 允许您使用协变返回类型来覆盖方法。

这意味着重写方法可以返回在重写方法上声明的类型的子类型。

在这种情况下,StringObject 是协变的;由于所有Strings 也是Objects,因此它是实现O.m1() O.m2() 的合适返回类型。

但是在一个类中不能有两个具有相同签名的方法(返回类型不是签名的一部分)。因此,当返回类型兼容时,您最多只能实现 1,如这里。 (如果它们不兼容,你会得到一个编译器错误)。

【讨论】:

  • 而至于问题的第一部分,见Overload with different return type in Java?
  • @AndyTurner return type is not part of the signature for javac, not JVM 和 AFAIK kotlin 以某种方式利用了这一点
  • @Eugene 返回类型是 JVM 中方法签名的一部分。但我们在这里讨论的是 Java,不是字节码,也不是 Kotlin。
  • @AndyTurner 对,这是完全正确的,顺便说一句,我给了一个加分,只是 kotlinc 确实以一种非常奇怪的方式使用了这个 IMO,我整个星期都在为此研究一个问题...
【解决方案2】:

StringObject 类的实例。因此,当您实现接口方法时,您可以更改类型转换。只有像int,double..and others 这样的原始类型 不能进行类型转换。

【讨论】:

  • 如何将 int 自动装箱为 Integer?
  • 你也可以使用带有自动装箱的原始类型。您可以使用原始类型的 Wrapper 对象更改类型转换。但不是原始类型。
  • 每个 int 都是一个 Integer,所以也是一个对象。但并非每个 Integer 都是 int,因为 Integer 并且每个其他对象都可以为 null,这与原语不同
【解决方案3】:

你可以用这个

class Test implements O, S {

    O  _o = new O() {
              @Override
              public Object m1(){
                return new Object();
              }
           };

    @Override
    public String m1(){
      return "";
    }
}

Test t = new Test();
t.m1();// m1 from s
t._o.m1();// m1 from O

【讨论】:

  • 你能快速解释一下第一个声明是如何工作的,或者给我一个解释它的链接吗? (O _o = new O() 然后打开括号并用“;”关闭它们,这是我第一次看到这个)
  • @Spn 是java中的一个匿名内部类,用作Test类的实例变量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
  • 2018-05-31
  • 2013-02-28
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多