12

考虑下面的例子,

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");
    }
}

如您所见,SupCls类和Intf接口之间没有联系。但两者都定义了一种通用方法。

并且Testing类正在扩展SupCls和实现Intf

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

From SupCls

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

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

Eclipse 的屏幕截图

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

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

编辑:如果重要的话,Eclipse 版本是Mars Release (4.5.0) 。

4

3 回答 3

11

您的假设是正确的,从超类继承的具体方法优先于以下default方法interface

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

一个类从其直接超类和直接超接口继承所有C abstract默认(第 9.4 节)方法m,以下所有方法都为真:

…</p>

  • 中声明的任何方法C的签名都不是m.
  • 从其直接超类继承的具体方法没有C一个签名是 的签名的子签名m

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

该文档甚至通过附加注释消除了任何疑问:

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

因此,在涉及到 class 时,它就像SupCls.test()覆盖。Intf.test()Testing

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

于 2015-09-09T11:12:46.543 回答
5

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

于 2015-09-09T08:30:33.013 回答
2

看起来eclipse版本很重要!

在 Eclipse Luna (4.4.1) 中,参考指向SupCls而不是Intf

在此处输入图像描述

可能是 Eclipse Mars 中的一个错误

于 2015-09-09T07:31:55.413 回答