Lambda FAQ_16.鑽石問題

鑽石問題

“鑽石問題”是允許多繼承所帶來的問題。對於允許狀態的多繼承語言來說(比如C++)這是一個嚴重的問題。但是,在Java中是不允許類的多繼承,僅僅允許接口多繼承,所以是不包含狀態的。

考慮下面的場景:
interface A {
        default void m() { ... }        
    }
interface B extends A {}
interface C extends A {}
class D implements B, C {}

根據上一章節說明的默認方法選擇規則,在類似這種場景中Java會有一種簡單直接的解釋方法。

如上代碼所示的這種場景,D所繼承的m方法的實現是沒有歧義的,因爲m方法只在A中定義。如果情況改變一下,B也聲明瞭方法m的實現,那麼D就會應用“最明確的實現”這一規則。但是如果B和C都提供了m的默認實現,那麼就會產生歧義,這時D就必須提供m的複寫聲明,可能是使用`X.super.m(..)`這種語法來顯示的選擇一個繼承的實現。這三種情況都在上一章節的“方法決議規則”中明確說明了。

默認方法和Java中所有的方法一樣,是虛擬的。這個有時會產生一些令人驚訝的結果。例如給定下面的聲明:
interface A {
    default void m() { System.out.println("hello from A"); }
}
interface B extends A {
    default void m() { System.out.println("hello from B"); }
}
interface C extends A {}
class D implements B, C {}

下面的代碼:
C c = new D();
c.m();
將會打印出hello from B。靜態的類型C並不重要,關鍵的是實際的類型是D,而D最明確的m聲明是從繼承B而來的。

原文地址


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章