Java 8中致命的死亡钻石

时间:2017-12-31 13:05:15

标签: java java-8

我是一名Java开发人员,我一直在学习C ++。我最近在C ++中进入了“致命的死亡之钻”并研究了这个问题是否可能在Java中出现。在Do interfaces solve the "deadly diamond of death" issue?中,我发现了这一点:

  

Java 8为方法搞砸了;界面现在可以声明两者   默认方法和静态方法实现。这带来了很大的影响   将死亡钻石的大块问题转化为语言。

我想知道是否有人能够扩展Java 8为DDD引入的问题。

2 个答案:

答案 0 :(得分:9)

我想quoted answer指的是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

可以通过覆盖x中的D来解决歧义(并满足编译器)。然后可以显式调用各个继承的默认方法:

class D implements B, C {
    @Override
    public void x() {
        B.super.x();       // Note explicit interface names
        C.super.x();
    }
}

<子> 1。显然,这里没有钻石。但这是一个更简单的案例。我们可以添加interface A { void x(); }B扩展的C,但这不会改变结果。

答案 1 :(得分:6)

有三种解决方案可以防止钻石问题:

Java-8 in Action 一书中说明:

  1. 课程总是胜利。类或超类中的方法声明优先于任何默认方法声明。

  2. 否则,子接口获胜:选择最具体的默认提供界面中具有相同签名的方法。 (如果B延伸A,则BA更具体。

  3. 最后,如果选择仍然不明确,那么从多个接口继承的类必须通过覆盖它并显式调用所需方法来显式选择要使用的默认方法实现。

  4. 如果由于某种原因仍然存在歧义,那么您的代码将无法编译。