JavaSE-Lambda表達式-02-201804
1.默認接口方法(default interface method)
背景:lambda表達式和方法引用大大提升了Java的表達能力(expressiveness),不過爲了使把代碼即數據(code-as-data)變的更加容易,我們需要把這些特性融入到已有的庫之中,以便開發者使用。但是接口發佈之後已定型,若要向接口添加新方法,則必須將以往所有該接口的實現同樣添加此新方法,這樣工程量就太大了。
默認方法(之前被稱爲虛擬擴展方法或守護方法)的目標即是解決這個問題,使得接口在發佈之後仍能被逐步演化。
默認方法利用面向對象的方式向接口增加新的行爲。它是一種新的方法:接口方法可以是抽象的或是默認的。默認方法擁有其默認實現,實現接口的類型通過繼承得到該默認實現(如果類型沒有覆蓋該默認實現)。此外,默認方法不是抽象方法,所以我們可以放心的向函數式接口裏增加默認方法,而不用擔心函數式接口的單抽象方法限制。
例如:Comparator接口中新增的默認方法Comparator<T> reversed()--比較器的逆序實現
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
解析:所有實現Comparator接口的類,都將繼承默認方法Comparator<T> reversed(),使用者可以根據情況決定是否重寫該方法。
注:當接口繼承其它接口時,我們既可以爲它所繼承而來的抽象方法提供一個默認實現,也可以爲它繼承而來的默認方法提供一個新的實現,還可以把它繼承而來的默認方法重新抽象化。
2.靜態接口方法(static interface method)
Java SE 8還在允許在接口中定義靜態方法。這使得我們可以從接口直接調用和它相關的輔助方法(Helper method),而不是從其它的類中調用(之前這樣的類往往以對應接口的複數命名,例如:Collections)。
例如:
public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
return Collections.reverseOrder();
}
3.繼承默認方法
和其它方法一樣,默認方法也可以被繼承。當類型或者接口的超類擁有多個具有相同簽名的方法時,我們就需要一套規則來解決這個衝突:
a.類的方法(class method)聲明優先於接口默認方法。無論該方法是具體的還是抽象的。
b.被其它類型所覆蓋的方法會被忽略。這條規則適用於超類型共享一個公共祖先的情況。
/**
* 1.當實現One,Two,Three三個接口時,編譯不過,原因是Two,Three中的default方法簽名相同導致衝突
* 2.類的方法(class method)聲明優先於接口默認方法。無論該方法是具體的還是抽象的
* */
public class Lambda02 extends Lpapa implements One,Two{
//此時Two中的plus()方法覆蓋了其父接口One的plus()方法
public static void main(String[] args) {
Lambda02 la=new Lambda02();
la.plus(); //打印出two
la.minus(); //打印處lpapa 類Lpapa的方法覆蓋了interface Two中的minus()
}
@Override
public void one() {
// TODO Auto-generated method stub
}
}
class Lpapa{
int n;
public void minus(){
System.out.println("lpapa");
}
}
interface One{
void one();
default void plus(){
System.out.println("one");
}
}
interface Two extends One{
default void plus(){
System.out.println("two");
}
default void minus(){
System.out.println("two-minus");
}
}
interface Three{
void three();
default void plus(){
System.out.println("three");
}
}
參考:http://www.cnblogs.com/figure9/p/java-8-lambdas-insideout-language-features.html