超类方法和接口默认方法冲突解决

2022-09-04 19:51:14

考虑下面的例子,

public class Testing extends SupCls implements Intf {
    public static void main(String[] args) {
        new Testing().test();
    }
}

class SupCls {
    public void test() {
        System.out.println("From SupCls");
    }
}

interface Intf {
    public default void test() {
        System.out.println("From Intf");
    }
}

如您所见,类和接口之间没有连接。但两者都定义了一种通用的方法。SupClsIntf

类正在扩展和实现。TestingSupClsIntf

所以,当我在输出上调用方法时,test()Testing

From SupCls

我认为这是有道理的,因为从类扩展应该比从接口实现具有更高的优先级。

但 eclipse 报告了其他情况,如下面的屏幕截图所示。

Screen Capture of Eclipse

我坚信这是Eclipse中的一个错误

但在假设之前,这种行为是否在JLS中定义和记录?还是有其他东西定义了这种行为?

编辑:Eclipse版本是火星发布(4.5.0),如果它很重要的话。


答案 1

您的假设是正确的,从超类继承的具体方法优先于 :defaultinterface

JLS §8.4.8.继承、覆盖和隐藏

类继承自其直接超类和直接超接口 all 和默认 (§9.4) 方法,对于这些方法,以下所有方法都为真:Cabstractm

...

  • 中声明的任何方法的签名都不是 的签名的子签名 (§8.4.2)。Cm
  • 从其直接超类继承的任何具体方法都没有签名,该签名是 的签名的子签名。Cm

引用的第二个项目符号在这里适用,有一个从直接超类继承的具体方法,具有适当的签名,因此该方法不被继承。default

该文档甚至通过附加说明清除了任何疑问:

请注意,继承的具体方法可能会阻止抽象方法或默认方法的继承。(稍后我们将断言具体方法覆盖了“来自C”的抽象或默认方法。

因此,当涉及到类时,它就像覆盖一样。SupCls.test()Intf.test()Testing

换句话说,你是对的,这是Eclipse中的一个错误,但只要它只影响提案的呈现方式,我就会认为这是一个小错误。插入的源将是相同的,无论是否在提案中呈现了D


答案 2

这当然是 eclipse 中的一个错误,但在代码完成建议中,而不是在编译器中。将鼠标悬停在测试调用或开放声明上会将您带到SupCls方法,并正确运行代码以打印“From SupCls”来证明这一点。请针对 jdt ui 提交错误以进行调查


推荐