Lambda FAQ_15.如何解決方法聲明之間的衝突

如何解決方法聲明之間的衝突?


因爲可以從多個接口繼承,所以相同的默認方法能夠從不同的路徑繼承而來。因爲每個繼承的默認方法提供不同的實現,編譯器需要一個一種方式來選擇使用哪個聲明。下面是編譯器的選擇方式:

  • 類總是優先的。在類或者子類中的聲明總是優先於所有的默認方法聲明。
  • 在有同樣簽名式的方法中選擇最明確提供默認方法的接口。例如,基於這個原則下面的代碼將輸出hello World from B:
public interface A {
        default void hello() { System.out.println("Hello World from A"); }
    }
    public interface B extends A {
        default void hello() { System.out.println("Hello World from B"); }
    }
    public class C implements B, A {
        public static void main(String... args) {
            new C().hello();
        }
    } 

衝突不是總能夠被避免。如果在上面的例子中,**接口B**沒有聲明繼承**A**,那麼C將從兩個沒有關係的接口繼承有同樣簽名式的默認方法。那麼編譯時上面的代碼將會產生如下的錯誤信息:
Class C從類型A和B繼承的沒有關係的默認方法hello()不明確,在A和B中都有方法hello()。

要注意的是上面的錯誤總會出現無論繼承的默認方法是否被調用。衝突必須通過複寫來解決。如果可能的話,繼承的默認方法可以通過這樣的語法來選擇`X.super.m(...)`,x是父接口而m是要選擇的方法:
public class C implements B, A {
        public void hello() {
            A.super.hello();
        }
        
}

現在這個代碼將輸出`Hello World from A`。注意的是,這個語法僅僅只能夠被用來解決衝突,而不能用來複寫上面列出的兩個原則。


原文地址

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