Java8 default關鍵字

在學習集合代碼時發(fā)現(xiàn)在Iterable接口中使用了default關鍵字。

default關鍵字介紹

default是在java8中引入的關鍵字,也可稱為Virtual
extension methods——虛擬擴展方法。是指,在接口內部包含了一些默認的方法實現(xiàn)(也就是接口中可以包含方法體,這打破了Java之前版本對接口的語法限制),從而使得接口在進行擴展的時候,不會破壞與接口相關的實現(xiàn)類代碼。

為什么要有這個特性?

首先,之前的接口是個雙刃劍,好處是面向抽象而不是面向具體編程,缺陷是,當需要修改接口時候,需要修改全部實現(xiàn)該接口的類,目前的java8之前的集合框架沒有foreach方法,通常能想到的解決辦法是在JDK里給相關的接口添加新的方法及實現(xiàn)。然而,對于已經(jīng)發(fā)布的版本,是沒法在給接口添加新方法的同時不影響已有的實現(xiàn)。所以引進的默認方法。他們的目的是為了解決接口的修改與現(xiàn)有的實現(xiàn)不兼容的問題。

如何使用default關鍵字?

1、調用父接口實現(xiàn)
創(chuàng)建接口Interface1,并且在接口Interface1中定義默認方法helloWorld()。

public interface Interface1{
    default void helloWorld() {
        System.out.println("hi i'm from Interface1");
    }
}

這時可以編寫一個類實現(xiàn)接口Interface1,并調用接口中定義的默認方法helloWorld(),代碼如下

/**
 * 實現(xiàn)接口Interface1
 */
public class MyImplement implements Interface1{
    public static void main(String[] args) {
        MyImplement myImplement = new MyImplement();
        //直接調用helloWorld()方法
        myImplement.helloWorld();
    }
}

可以看到,執(zhí)行的結果為我們之前在接口Interface1中定義的默認方法。

此時的類圖為

2、同時繼承兩個接口

創(chuàng)建接口Interface2,接口Interface2中也定義了默認方法helloWorld()。

public interface Interface2{
    default void helloWorld() {
        System.out.println("hi i'm from Interface2");
    }
}

這時候讓類MyImplement同時實現(xiàn)Interface1和Interface2,代碼如下:

/**
 * 實現(xiàn)接口Interface1,Interface2
 */
public class MyImplement implements Interface1,Interface2{
    public static void main(String[] args) {
        MyImplement myImplement = new MyImplement();
        //直接調用helloWorld()方法
        myImplement.helloWorld();
    }
}

此時會發(fā)現(xiàn)編譯器報錯,報錯信息如下:

發(fā)生這種情況的原因是,實現(xiàn)類MyImplement即實現(xiàn)了接口Interface1又實現(xiàn)了接口Interface2,恰巧兩個接口中都定義可相同的默認方法。說白了就是編譯器此時已經(jīng)被干懵了,當我們在MyImplement類中調用方法時,它不知道該去調用Interface1的默認方法還是去調用Interface2的方法。解決方法就是在實現(xiàn)類中實現(xiàn)該方法。代碼如下

public class MyImplement implements Interface1,Interface2 {

    @Override
    public void helloWorld() {
        System.out.println("hi i'm from MyImplement");
    }

    public static void main(String[] args) {
        MyImplement myImplement = new MyImplement();
        myImplement.helloWorld();
    }
}

執(zhí)行代碼控制臺輸出如下:

此時的類圖為

3、類優(yōu)先于接口
此時創(chuàng)建一個實現(xiàn)類MyImplement2,該實現(xiàn)類不僅繼承了MyImplement1并且實現(xiàn)了Interface2。
實現(xiàn)類MyImplement2的代碼如下

public class MyImplement2 extends MyImplement implements Interface2{

    public static void main(String[] args) {
        MyImplement2 myImplement2 = new MyImplement2();
        myImplement2.helloWorld();
    }

}

此時的類圖為

此時在實現(xiàn)類MyImplement2中調用helloWorld()方法,到底執(zhí)行的是MyImplement中的方法還是執(zhí)行Interface2中的方法?
答:因為類優(yōu)先于接口,所以將會執(zhí)行MyImplement中的方法。

執(zhí)行結果如下

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容