如何使用 Java 中的默认方法解决钻石问题

继承 是两个类之间的关系,其中一个类继承另一个类的属性。这种关系可以使用 extends 关键字定义为 -

public class A extends B{}

继承属性的类称为子类或子类,继承属性的类称为超类或父类。

在继承中,在子类对象中创建了超类成员的副本。因此,使用子类对象可以访问这两个类的成员。

多重继承是一个类继承多个类的属性。换句话说,在多重继承中,我们可以有一个子类和 n 个父类。Java 不支持多重继承(使用类)。

钻石问题

  • 例如,让我们假设 Java 确实支持多重继承。

  • 如果我们有一个名为Sample的抽象类,它有一个抽象方法demo()。

  • 那么如果同一个包中的另外两个类扩展了这个类并尝试实现它的抽象方法,demo().

  • 然后,根据继承的基本规则,demo()应在子类对象中创建两个方法的副本,从而使子类具有两个具有相同原型(名称和参数)的方法。

  • 那么,如果demo()使用子类的对象调用方法,编译器就会面临不知道调用哪个方法的模棱两可的情况。这个问题在 Java 中被称为钻石问题。

钻石问题的解决方案

您可以使用默认方法 (Java8) 和接口在 Java 中实现多重继承。

从 Java8 开始,接口中引入了默认方法。与其他抽象方法不同,这些是具有默认实现的接口的方法。如果您在接口中有默认方法,则不必在已经实现此接口的类中覆盖(提供主体)它。

您可以在两个不同的接口中拥有相同的默认方法(相同的名称和签名),并且您可以从一个类中实现这两个接口。

如果这样做,则必须覆盖类中的默认方法,显式指定默认方法及其接口名称。

示例

interface MyInterface1{  
   public static int num = 100;
   public default void display() {
      System.out.println("display method of MyInterface1");
   }
}
interface MyInterface2{  
   public static int num = 1000;
   public default void display() {
      System.out.println("display method of MyInterface2");
   }
}  
public class InterfaceExample implements MyInterface1, MyInterface2{
   public void display() {
      MyInterface1.super.display();
      //or,
      MyInterface2.super.display();
   }      
   public static void main(String args[]) {
      InterfaceExample obj = new InterfaceExample();
      obj.display();
   }
}
输出结果
display method of MyInterface1
display method of MyInterface2