Java 8 接口
Java8 之前的接口定義中,方法的方法體必須是空的,接口不允許定義實例變量。并且接口實現類必須實現接口定義的所有方法。從Java 8 開始,接口可以定義默認方法,而且所有接口實現類都可以改方法及實現。
默認方法和抽象方法的區別是抽象方法必須要被實現,默認方法不是。作為替代方式,接口可以提供一個默認的方法實現,所有這個接口的實現類都會通過繼承得到這個方法(如果有需要也可以重寫這個方法)
默認方法定義
public interface DefaultFuncInter {
??? int getInt();
??? default String getString(){
??????? return "Default String";
??? }
}
默認方法優勢
- 提供一種拓展接口的方法,而不破壞現有代碼。
假如我們有一個已經投入使用的接口需要拓展一個新的方法,在JDK8以前,如果為一個使用的接口增加一個新方法,則我們必須在所有實現類中添加該方法的實現,否則編譯會出現異常。如果實現類數量少并且我們有權限修改,可能會工作量相對較少。如果實現類比較多或者我們沒有權限修改實現類源代碼,這樣可能就比較麻煩。而默認方法則解決了這個問題,它提供了一個實現,當沒有顯示提供其他實現時就采用這個實現。這樣新添加的方法將不會破壞現有代碼。
注意:擴展方法不能夠重寫(也稱復寫或覆蓋) Object 中的方法,卻可以重載Object 中的方法。
- 默認方法是可選的,子類可以根據不同的需求Override默認實現。
例如,我們定義一個集合接口,其中有增、刪、改等操作。如果我們的實現類90%都是以數組保存數據,那么我們可以定義針對這些方法給出默認實現,而對于其他非數組集合或者有其他類似業務,可以選擇性復寫接口中默認方法。
多重繼承的沖突說明:
由于同一個方法可以從不同接口引入,自然而然的會有沖突的現象,規則如下:
1)一個聲明在類里面的方法優先于任何默認方法
2)優先選取最具體的實現
3)如果繼承多個同名的默認方法,則必須在類中重寫默認方法,提高優先級。
接口靜態方法
Java8接口中可以定義靜態方法,只能通過接口名調用,不可以通過實現類的類名或者實現類的對象調用。類似類的靜態方法。
public interface DefaultFuncInter {
??? int getInt();
??? static int add(int a,int b){
??????? return a + b;
??? }
}
由于靜態方法只能通過接口來類來調用,所以不會出現多個接口的相同方法沖突的問題。
函數式接口
Java8開始支持Lambda表達式,一個lambda表達式都對應一個類型,通常是接口類型。而“函數式接口”是指僅僅只包含一個抽象方法的接口,每一個該類型的lambda表達式都會被匹配到這個抽象方法。因為 默認方法 不算抽象方法,所以你也可以給你的函數式接口添加默認方法。
@FunctionalInterface
interface Converter<F, T> {
??? T convert(F from);
}
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted);??? // 123
?
邏輯與 符號
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey());}& 表示lambda表達式是可以轉換成的對象,可以滿足2個接口
總結
- 上一篇: 泛型的协变与逆变
- 下一篇: hamcrest详细介绍