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.