考虑下面的例子,
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中的错误。
但在假设之前,是否已定义此行为&记录在 JLS 中?或者还有其他什么来定义这种行为?
编辑:Eclipse版本 Mars Release(4.5.0),如果重要的话。
答案 0 :(得分:9)
您的假设是正确的,从超类继承的具体方法优先于default
中的interface
方法:
JLS §8.4.8. Inheritance, Overriding, and Hiding
类
C
从其直接超类继承并直接重叠所有abstract
和默认(§9.4)方法m
,以下所有方法都是真:...
C
中声明的方法没有签名是m
签名的子签名(第8.4.2节)。C
从其直接超类继承的具体方法没有签名,该签名是m
签名的子签名。
第二个引用的子弹适用于此处,有一个从具有适当签名的直接超类继承的具体方法,因此default
方法不会被继承。
文档甚至可以通过额外的评论清除任何疑问:
请注意,继承的具体方法可能会阻止抽象或默认方法的继承。 (稍后我们将声明具体方法覆盖了“来自C”的抽象或默认方法。)
因此SupCls.test()
就类Intf.test()
而言覆盖Testing
。
换句话说,你是对的,这是Eclipse中的一个错误,但只要它只影响提案的呈现方式,我就认为它是次要的错误。无论是否在提案中呈现 D ,插入的源都是相同的。
答案 1 :(得分:5)
这肯定是eclipse中的一个错误,但在代码完成提案中而不是在编译器中。将鼠标悬停在测试或打开声明的调用上,将转到SupCls方法并正确运行代码,打印“From SupCls”,证明了这一点。请提交针对jdt ui进行调查的错误
答案 2 :(得分:2)