2

我正在研究 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变成了一个interfacewithdefault方法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继承了 a default(from A) 和 an abstract print()(from B) 的事实。

解决方案是定义一个abstract print()in 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
    }
}

有谁知道在从 a 继承 a 和从父类继承它之间是否存在这种不对称行为的特殊default method原因interface

这里是否以某种方式涉及致命的死亡钻石(我不明白为什么)?

4

1 回答 1

2

您需要print()在 C 中实现:

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

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

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

于 2016-06-19T13:33:25.627 回答