java accidential隐式接口实现

时间:2010-12-23 12:05:07

标签: java inheritance compiler-construction polymorphism

最近遇到了一个有趣的功能,但这会导致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()
}

3 个答案:

答案 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   class C会覆盖另一个实例   方法m2,在类A iff中声明   以下所有都是真的:

     
      
  • CA的子类。
  •   
  • m1的签名是m2签名的子签名(第8.4.2节)。
  •   
  • 要么   
        
    • m2在与C相同的包中公开,受保护或声明为默认访问权限,或
    •   
    • m1会覆盖方法m3m3m1不同,m3m2不同,以便m3覆盖m2
    •   
  •   

在您的情况下,第一个条件不满足:方法callme在类CallMeCode中声明,而不是CallmeIfc的子类型。

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

  

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

规范没有解释原因。