java意外隐式接口实现

问题描述 投票:0回答:3

最近遇到一个有趣的功能,不过,它可能会导致 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()
}
java inheritance polymorphism
3个回答
2
投票

在 CallmeImpl 中,公共 callme() 方法继承自 CallmeCode,因此 CallmeImpl 遵循 CallmeIfc 中定义的约定。

然后,在 main() 方法中,多态性允许您将子类实例 (CallmeImpl) 分配给超类或超接口引用 - 在这种特殊情况下,是 CallmeIfc 类型的“me”引用(这里有一个拼写错误,顺便说一句).


1
投票

实际上,对我来说,这看起来像是一个编译器错误:Java 语言规范写道

在 a 中声明的实例方法

m1
C
覆盖另一个实例 方法,
m2
,在类
A
中声明 iff 以下所有内容均正确:

  • C
    A
    的子类。
  • m1
    的签名是
    m2
    签名的子签名(第8.4.2节)。
  • 无论是
    • m2
      是公共的、受保护的或在与
      C
      相同的包中声明为默认访问权限,或者
    • m1
      覆盖方法
      m3
      m3
      m1
      不同,
      m3
      m2
      不同,使得
      m3
      覆盖
      m2

在您的情况下,不满足第一个条件:方法

callme
在类
CallMeCode
中声明,它不是
CallmeIfc
的子类型。

编辑:Bobah 是对的,规范区分了实现和覆盖。事实上,它实际上强制观察到的行为:

除非所声明的类是 摘要,所有声明 每个直接的方法成员 必须实现超级接口 通过此类中的声明 或通过现有的方法声明 从直接超类继承, 因为一个类不是抽象的 不允许有摘要 方法

规范没有解释原因。


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。如果该方法被命名为不同的,它将无法编译。

© www.soinside.com 2019 - 2024. All rights reserved.