5

考虑以下代码:

public interface A {
  public A another();
}

public interface B {
  public B another();
}

public interface AB extends A,B {
  public AB another();
}

这会导致编译错误AB

B 型和 A 型不兼容;都定义了另一个(),但返回类型不相关

我已经看到了这个SO question,并按照接受的答案中的不兼容示例进行操作 - 即

public interface C { 
  public void doSomething();
}

public interface D {
  public boolean doSomething();
}

public interface CD extends C,D { 
}

但是,在那种情况下,返回类型是真正不兼容的——返回类型不能既是 void 又是布尔值。然而,在我上面的例子中,another()返回类型AB是 anA和 a B,所以可以实现这两个扩展接口。

此外,看过 JLS(8.4.8、8.4.8.3、8.4.8.4)后,我不太明白为什么我上面的例子是非法的。谁能给我解释一下?

A其次,除了重复或B中的合同要求之外,是否有任何解决方案/解决方法AB

4

1 回答 1

12

对于 1.5 之前的 Java 版本会出现此错误消息(至少我可以在 Eclipse 中将合规级别设置为 1.4 时重现该错误)。换句话说,请确保您正在查看足够旧的规格。

在 Java >= 1.5 上,以下编译良好。

interface A {
    public A another();
}

interface B {
    public B another();
}

interface AB extends A,B {
    public AB another();
}

正如您所说,因为ABisA和 a B,它都满足两个接口。


这是Java语言规范(第二版,即Java 1.4)的引述:

9.2 接口成员

接口的成员是:

  • 在接口中声明的那些成员。
  • 那些从直接超级接口继承的成员
  • 如果接口没有直接的超级接口,则 [...]

因此,如果接口声明了具有相同签名和不同返回类型的方法或不兼容的 throws 子句,则它是编译时错误。

此外,当前的规范说明了以下内容:

9.4.2 重载

如果一个接口的两个方法(无论是在同一个接口中声明,还是都由接口继承,或者一个声明一个继承)具有相同的名称但不同的签名不是覆盖等效的(第 8.4.2 节),那么方法名称被称为重载。这个事实不会造成任何困难,而且它本身也不会导致编译时错误。返回类型之间或两个具有相同名称但签名不同但不是覆盖等效的方法的 throws 子句之间没有必需的关系。

于 2012-07-05T11:21:42.547 回答