若類可繼承多個父類,且多個父類繼承自同一基類,子類調用基類方法時會出現二義性——不知道調用哪個父類的實現。這就是經典的「鑽石問題」。
A
/ \
B C
\ /
D → D 調用 A.method() 時,走 B 還是 C?
extends 只能有一個父類,從根源消除鑽石結構implements 可實現多個接口,接口傳統上無實現代碼,無二義性JDK 8 引入 default 方法,接口可有實現,理論上重現鑽石問題:
interface A { default void foo() { ... } }
interface B extends A { default void foo() { ... } }
interface C extends A { default void foo() { ... } }
class D implements B, C { } // D 調用 foo() 怎麼辦?
Java 強制規則:
B.super.foo() 顯式指定調用哪個接口實現class D implements B, C {
@Override public void foo() { B.super.foo(); } // 必須顯式選擇
}
| 語言 | 多繼承策略 | 特點 |
|---|---|---|
| C++ | 支援,虛繼承解決鑽石 | 複雜、靈活、易誤用 |
| Python | 支援,MRO 線性化算法 | 動態、隱式、需理解 C3 算法 |
| Java | 類單繼承 + 接口多實現 | 簡單、明確、編譯期強制消除歧義 |
Java 拒絕類多繼承,是為了簡單性、健壯性、編譯期安全的工程權衡。JDK 8 默認方法在保持兼容性的同時,通過強制顯式重寫再次守住了這條底線。