Java 8中致命的死亡钻石
我是一名Java开发人员,我一直在学习C ++。 我最近在C ++中进入了“致命的死亡钻石”,并研究了这个问题是否可能在Java中出现。 在Do界面解决“致命的死亡钻石”问题? , 我找到了这个:
Java 8为方法搞砸了; 现在,接口可以声明默认方法和静态方法实现。 这将大量的死亡钻石问题带入语言。
我想知道是否有人能够扩展Java 8为DDD引入的问题。
我想引用的答案是指Java中的这种情况: 1
interface B { default void x() { System.out.println("B::x"); } } interface C { default void x() { System.out.println("C::x"); } } class D implements B, C {}
什么会像new D().x()
这样做?
幸运的是,编译器完全禁止D
的定义,并带有以下消息:
D inherits unrelated defaults for x() from types B and C
通过覆盖D
x
,可以解决模糊性(并满足编译器)。 然后可以显式调用各个inheritance的默认方法:
class D implements B, C { @Override public void x() { B.super.x(); // Note explicit interface names C.super.x(); } }
很明显,这里没有钻石。 但这是一个更简单的案例。 我们可以添加interface A { void x(); }
B
和C
扩展,但这不会改变结果。
有三种解决方案规则可以防止钻石问题:
在Java-8 in Action书中说明:
-
课程总是胜利。 类或超类中的方法声明优先于任何默认方法声明。
-
否则,子接口获胜:选择在最特定的默认提供接口中具有相同签名的方法。 (如果
B
延伸A
,则B
比A
更具体)。 -
最后,如果选择仍然不明确,则从多个接口inheritance的类必须通过覆盖它并显式调用所需方法来显式选择要使用的默认方法实现。
如果由于某种原因仍然存在任何歧义,那么您的代码将无法编译。