我正在学习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}}之间存在这种不对称行为的特定原因?
这里有致命的死亡钻石(我不明白为什么)?
答案 0 :(得分:2)
您需要在C:
中实施print()
class C implements A,B {
public void useInheritedPrint() {
print(); // should print A
}
@Override
public void print() {
A.super.print();
}
}
基本原理是,如果您使用相同的签名继承两个可能存在冲突的方法,则需要显式实现该方法并选择其中一个实现(或定义一个新实现)。