最近遇到一个有趣的功能,不过,它可能会导致 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()
}
在 CallmeImpl 中,公共 callme() 方法继承自 CallmeCode,因此 CallmeImpl 遵循 CallmeIfc 中定义的约定。
然后,在 main() 方法中,多态性允许您将子类实例 (CallmeImpl) 分配给超类或超接口引用 - 在这种特殊情况下,是 CallmeIfc 类型的“me”引用(这里有一个拼写错误,顺便说一句).
实际上,对我来说,这看起来像是一个编译器错误:Java 语言规范写道:
在 a 中声明的实例方法
类m1
覆盖另一个实例 方法,C
,在类m2
中声明 iff 以下所有内容均正确:A
是C
的子类。A
的签名是m1
签名的子签名(第8.4.2节)。m2
- 无论是
是公共的、受保护的或在与m2
相同的包中声明为默认访问权限,或者C
覆盖方法m1
,m3
与m3
不同,m1
与m3
不同,使得m2
覆盖m3
。m2
在您的情况下,不满足第一个条件:方法
callme
在类CallMeCode
中声明,它不是CallmeIfc
的子类型。
编辑:Bobah 是对的,规范区分了实现和覆盖。事实上,它实际上强制观察到的行为:
除非所声明的类是 摘要,所有声明 每个直接的方法成员 必须实现超级接口 通过此类中的声明 或通过现有的方法声明 从直接超类继承, 因为一个类不是抽象的 不允许有摘要 方法
规范没有解释原因。
虽然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。如果该方法被命名为不同的,它将无法编译。