Java 8新特性探究(二)深刻解析默認方法

上篇講了 lambda表達式的語法,但只是 JEP126 特性的一部分,另外一部分就是默認方法(也稱爲虛擬擴展方法或防禦方法)
java

什麼是默認方法,爲何要有默認方法

簡單說,就是接口能夠有實現方法,並且不須要實現類去實現其方法。只需在方法名前面加個default關鍵字便可。

爲何要有這個特性?首先,以前的接口是個雙刃劍,好處是面向抽象而不是面向具體編程,缺陷是,當須要修改接口時候,須要修改所有實現該接口的類,目前的java 8以前的集合框架沒有foreach方法,一般能想到的解決辦法是在JDK裏給相關的接口添加新的方法及實現。然而,對於已經發布的版本,是無法在給接口添加新方法的同時不影響已有的實現。因此引進的默認方法。他們的目的是爲了解決接口的修改與現有的實現不兼容的問題。編程

簡單的例子

一個接口A,Clazz類實現了接口A。
框架

public interface A {
    default void foo(){
       System.out.println("Calling A.foo()");
    }
}
  
public class Clazz implements A {
    public static void main(String[] args){
       Clazz clazz = new Clazz();
       clazz.foo();//調用A.foo()
    }
}

代碼是能夠編譯的,即便Clazz類並無實現foo()方法。在接口A中提供了foo()方法的默認實現。ide

java 8抽象類與接口對比

這一個功能特性出來後,不少同窗都反應了,java 8的接口都有實現方法了,跟抽象類還有什麼區別?其實仍是有的,請看下錶對比。。 函數

相同點 不一樣點

1.都是抽象類型;spa

2.均可以有實現方法(之前接口不行);.net

3.均可以不須要實現類或者繼承者去實現全部方法,(之前不行,如今接口中默認方法不須要實現者實現)設計

1.抽象類不能夠多重繼承,接口能夠(不管是多重類型繼承仍是多重行爲繼承);code

2.抽象類和接口所反映出的設計理念不一樣。其實抽象類表示的是"is-a"關係,接口表示的是"like-a"關係;orm

3.接口中定義的變量默認是public static final 型,且必須給其初值,因此實現類中不能改變其值;抽象類中的變量默認是 friendly 型,其值能夠在子類中從新定義,也能夠從新賦值。 

多重繼承的衝突說明

因爲同一個方法能夠從不一樣接口引入,天然而然的會有衝突的現象,默認方法判斷衝突的規則以下:

1.一個聲明在類裏面的方法優先於任何默認方法(classes always win)

2.不然,則會優先選取最具體的實現,好比下面的例子 B重寫了A的hello方法。

輸出結果是:Hello World from B

若是想調用A的默認函數,則用到新語法X.super.m(...),下面修改C類,實現A接口,重寫一個hello方法,以下所示:

public class C implements A{
   
    @Override
    public void hello(){
        A.super.hello();
    }
    
    public static void main(String[] args){
        new C().hello();
    }
}

輸出結果是:Hello World from A

總結

默認方法給予咱們修改接口而不破壞原來的實現類的結構提供了便利,目前java 8的集合框架已經大量使用了默認方法來改進了,當咱們最終開始使用Java 8的lambdas表達式時,提供給咱們一個平滑的過渡體驗。也許未來咱們會在API設計中看到更多的默認方法的應用。

跟上篇博文結合起來,就是JEP126的所有了,後面還有54個特性等着咱們去探究,爲了讓你們比較深入瞭解lambda,學以至用,下一篇仍是lambda的內容,預告一下下篇的標題:《Java 8特性探究(三)解開lambda表達式最強做用的神祕面紗》,第二個特性 將從第四篇開始,謝謝你們支持,敬請期待。。。

轉載時候請註明出處。 http://my.oschina.net/benhaile

相關文章
相關標籤/搜索