Java 8中致命的死亡钻石

JNM*_*NMN 2 java java-8

我是一名Java开发人员,我一直在学习C++.我最近在C++中进入了"致命的死亡钻石"并研究了这个问题是否可能在Java中出现.在Do界面解决"致命的死亡钻石"问题?, 我找到了这个:

Java 8为方法搞砸了; 现在,接口可以声明默认方法和静态方法实现.这将大量的死亡钻石问题带入语言中.

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

Oli*_*rth 10

我想引用的答案是指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 {}
Run Code Online (Sandbox Code Playgroud)

这会是什么样的new D().x()事情?

幸运的是,编译器D完全禁止完全定义,并带有以下消息:

D inherits unrelated defaults for x() from types B and C
Run Code Online (Sandbox Code Playgroud)

人们可以解决不确定性(和满足编译器)通过覆盖xD.然后可以显式调用各个继承的默认方法:

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

很明显,这里没有钻石.但这是一个更简单的案例.我们可以添加interface A { void x(); }两个BC扩展,但不会改变这一结果.


Ous*_* D. 6

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

Java-8 in Action书中说明:

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

  2. 否则,子接口win:选择在最特定的默认提供接口中具有相同签名的方法.(如果B扩展A,B则更具体A).

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

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