Java8中的钻石概率解析或多重继承的规则

时间:2017-02-14 09:45:38

标签: java oop java-8 diamond-problem default-method

在Java中,类只能扩展一个父类,但可以实现多个接口。 同 在Java 8界面中引入默认方法,有一个类继承多个的可能性 通过实现具有相同默认方法的2个接口,具有相同签名的方法 这可能会像C ++中那样产生钻石问题

下面的代码示例

的输出
new C().hello(); is 
  

这是第二次

   public interface First {

    default void hello(){
        System.out.println("This is First");
    }
}

 public interface Second extends First {

    default void hello(){
        System.out.println("This is Second");
    }
}

  public class MyClass implements First,Second {

    public static void main(String[] args) {
        new MyClass().hello();
    }
}

Java用于解决钻石问题的解决方案规则是什么? 一个简单的答案,如谁优先,什么时候会很棒。

4 个答案:

答案 0 :(得分:4)

Oracle Tutorial可以详细解释这一点。

您基本上已从First接口覆盖您的方法,并选择了最具体的接口方法。

答案 1 :(得分:4)

以下是当一个类从多个地方(另一个类或接口)继承具有相同签名的方法时要遵循的规则:

  • 课程总是胜利。类或超类中的方法声明 优先于任何默认方法声明。
  • 否则,子接口win:在最具体的defaultproviding中具有相同签名的方法 界面被选中。 (例如在你的情况下,来自Second接口的方法应该以Second扩展First的方式运行。)
  • 最后,如果选择仍然不明确,则继承自多个接口的类必须 通过覆盖它并调用它来显式选择要使用的默认方法实现 期望的方法明确。

答案 2 :(得分:2)

您的代码段没有钻石问题,因为接口第二个扩展接口并覆盖方法hello。

如果没有扩展接口,则编译器会抛出错误

Duplicate default methods named hello with the parameters () and () are inherited from the types Second and First

答案 3 :(得分:2)

实现两个声明相同默认方法的接口会导致编译错误:

MyClass inherits unrelated defaults for sayHi() from types InterfaceA and InterfaceB 

所以没有钻石问题;)

要解决此问题,您可以覆盖实现类中的Method,并在那里实现它或者遵循正确的接口。

在你的情况下它看起来像那样(如果你想使用接口First的方法):

 public class MyClass implements First,Second {
     public void hello() {
         First.super.hello();
     }
 }