Java 多继承中的菱形问题是什么?


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

public class A extends B{
}

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

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

多继承

存在各种类型的继承,即单继承、多级继承、层次继承、多继承和混合继承。

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

菱形问题

例如,让我们假设 Java 支持多继承。基于此假设,请考虑以下示例。

示例

这里,我们有一个名为 Sample 的抽象类,其中包含一个抽象方法:

public class abstract Sample {
   public abstract demo();
}

然后在同一个包/文件夹中,我们有两个类扩展了这个类并尝试实现其抽象方法 `demo()`。

public class Super1 extends Sample{
   public void demo() {
      System.out.println("demo method of super1");
   }
}
public class Super2 extends Sample{
   public void demo() {
      System.out.println("demo method of super2");
   }
}

根据我们的假设,由于 Java 支持多继承,我们试图继承 Super1 和 Super2 两个类。

public class SubClass extends Super1, Super2 {
   public static void main(String args[]) {
      SubClass obj = new SubClass();
      obj.demo();
   }
}

然后,根据继承的基本规则,`demo()` 方法的副本应该在子类对象中创建,这使得子类拥有两个具有相同原型(名称和参数)的方法。然后,如果您使用子类对象调用 `demo()` 方法,编译器将面临一个不明确的情况,不知道调用哪个方法。这个问题在 Java 中被称为菱形问题。

由于这个原因,Java 不支持多继承,即您不能扩展多个其他类。如果您仍然尝试这样做,则会生成编译时错误。

编译时错误

编译上述程序时,会生成以下错误:

MultipleInheritanceExample.java:9: error: '{' expected
public class MultipleInheritanceExample extends MyInterface1, MyInterface2{
^
1 error

解决方案

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

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

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

如果您这样做,则必须显式地覆盖来自类的默认方法,并同时指定默认方法及其接口名称。

示例

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

更新于:2020年7月2日

12K+ 浏览量

启动你的职业生涯

完成课程获得认证

开始学习
广告
© . All rights reserved.