为什么继承的default-method不能像继承的类方法那样实现另一个接口?

时间:2016-06-19 13:28:58

标签: java inheritance java-8 override default-method

我正在学习Java 8,我遇到了一种我无法完全理解的default方法的行为。

首先,一个“老派”Java代码片段可以完美地编译和运行:

abstract class A {
    public void print() {
        System.out.println("A");
    }
}
interface B {
    void print(); // implicitly public and abstract
}
class C extends A implements B {
    public void useInheritedPrint() {
      print(); // prints A
    }
}

C继承了来自print()的已实施A和来自print()的抽象B,这被视为已正确实施。

但如果A成为interface default方法print(),则如下:

interface A { 
    default void print() { // implicitly public
        System.out.println("A");
    }
}
interface B {
    void print(); // implicitly public and abstract
}
class C implements A,B {
    public void useInheritedPrint() {
      print(); // should print A
    }
}

即使C仍然从print()继承A,编译器也会抱怨C不是abstract这一事实(如果A是一个如前所示的类)。如果C变为abstract,则如下所示:

abstract class C implements A, B {
  public void useInheritedPrint() {
    print();
  }
}

然后编译器抱怨C继承了default(来自A)和abstract print()(来自B这一事实})。

解决方案是在abstract print()中定义C,如下:

class C implements A,B {
    public void useInheritedPrint() {
      print(); // should print A
    }
    public abstract void print(); // shall be implemented by a concrete subclass
}

或覆盖print(),如:

class C implements A,B {
    public void useInheritedPrint() {
      print(); // should print A
    }
    public void print() { 
      // do something
    }
}

是否有人知道从default method继承interface并从父类继承{{1}}之间存在这种不对称行为的特定原因?

这里有致命的死亡钻石(我不明白为什么)?

1 个答案:

答案 0 :(得分:2)

您需要在C:

中实施print()
class C implements A,B {
    public void useInheritedPrint() {
      print(); // should print A
    }

    @Override
    public void print() {
        A.super.print();
    }
}

基本原理是,如果您使用相同的签名继承两个可能存在冲突的方法,则需要显式实现该方法并选择其中一个实现(或定义一个新实现)。