最近遇到了一个有趣的功能,但这会导致Eclipse的“添加未实现的方法”功能的意外输出。这种“偶尔隐式实现”背后的语言概念的“googl-able”名称是什么?
我不希望下面的代码编译,但它确实并且正在运行
interface CallmeIfc {
public void callme();
}
class CallmeCode {
public void callme() {
// implementation
}
}
class CallmeImpl extends CallmeCode implements CallmeIfc {
// empty class body
}
public static void main(String[] args) {
CallmeIfc me = (CallmeIfc) new CallmeImpl();
me.callme(); // calls CallmeCode.callme()
}
答案 0 :(得分:2)
在CallmeImpl中,public callme()方法继承自CallmeCode,因此CallmeImpl尊重CallmeIfc中定义的契约。
然后,在你的main()方法中,多态允许你将子类实例(CallmeImpl)分配给超类或超接口引用 - 在这种特殊情况下,类型为CallmeIfc的“我”引用(这里有一个错字) ,BTW)。
答案 1 :(得分:1)
虽然CallmeCode类没有实现CallmeIfc接口,但它提供了必要的实现。就好像CallmeCode类实现了接口一样。它也适用于这段代码:
interface CallmeIfc {
public void callme();
}
class CallmeCode implements CallmeIfc {
public void callme() {
// implementation
}
}
class CallmeImpl extends CallmeCode implements CallmeIfc {
// empty class body
}
在你的情况下这很好,因为类CallmeCode有一个方法callme。如果该方法的名称不同,则无法编译。
答案 2 :(得分:1)
实际上这看起来像编译器错误:Java语言规范writes:
在a中声明的实例方法
m1
classC
会覆盖另一个实例 方法m2
,在类A
iff中声明 以下所有都是真的:
C
是A
的子类。m1
的签名是m2
签名的子签名(第8.4.2节)。- 要么
m2
在与C
相同的包中公开,受保护或声明为默认访问权限,或m1
会覆盖方法m3
,m3
与m1
不同,m3
与m2
不同,以便m3
覆盖m2
。
在您的情况下,第一个条件不满足:方法callme
在类CallMeCode
中声明,而不是CallmeIfc
的子类型。
编辑:Bobah是对的,Spec区分了实现和覆盖。事实上,它实际上是mandates观察到的行为:
除非被宣布的类是 摘要,所有的声明 方法成员每个直接 必须实现超接口 通过本课程中的声明 或通过现有的方法声明 继承自直接超类, 因为一个不抽象的类 不允许有摘要 方法
规范没有解释原因。