Java8新特性之default關鍵字學習

先談一談抽象類和接口的區別

抽象類

可看做是不可實例化的普通類,可以擁有構造方法,可以有main方法

抽象類中的方法可以是抽象方法(抽象方法必須存在於抽象類中),也可以是普通方法、靜態方法

可以聲明變量,不是必須賦初值。

抽象類可以繼承其它類,也可實現接口

抽象類的派生類,必須覆蓋父類中abstract修飾的所有方法

接口

接口僅可繼承其他接口,不可繼承其它類或實現另外的接口

接口中的方法默認爲abstract類型

接口中聲明的變量必須賦初值,且不可再改變,因爲所有變量都是static final類型的

對於JDK7及以前版本:

1. 接口中的方法不可有方法體(因爲默認是抽象方法),不可有靜態方法。

2. 接口的實現類,必須實現接口中的所有方法(包括接口本身的和從其它接口繼承的)

對於JDK8及以後版本:

1. 接口中default方法可有方法體,也可在接口裏寫靜態方法。

2. 接口的實現類,必須實現接口中除default類型的其它所有方法(包括接口本身的和從其它接口繼承的)

再說說default關鍵字:

自Java8加入

用來修飾方法,使得在接口中的方法可以寫入方法體

接口的實現類若沒有實現(也可以叫覆蓋)default類型的方法,則可在實現類中直接調用(接口says:你不覆蓋,那就按這個默認的來了啊)。否則,是正常的覆蓋,實現多態。

個人理解:

1. default的加入,使得我們在接口類中增加方法時,不必一個個地改動實現類了(添加一個default方法時,實現類可以不去管),使得接口和抽象類更爲貼近了一步。

2. 很多的抽象類可以被精簡掉了,實現接口的抽象類中寫的方法體代碼可以直接移到接口中,派生類直接實現接口即可,具體可以看WebMvcConfigurerAdapter被廢棄的例子

附上一個實驗例子,兩個接口是繼承關係,一個類來實現其中一個接口,實驗各種調用:

interface BaseRadio {

    void sent(String a,String b);

    int port = 9800;

    default void close() {
        System.out.println(port);
        System.out.println("關了");
    }

    static void prt(){
        System.out.println("uvb77");
    }

    default void open() {
        System.out.println("打開");
    }
}
interface Radio extends BaseRadio {

    void sent();

    void sent(int s);

    int sent(String a);

    @Override
    default void close() {
        System.out.println(port + 1);
        System.out.println("我是Radio重寫的");
    }

    static void prt(){
        System.out.println("uvb76");
    }

}
public class TestRadio implements Radio {

    @Override
    public void sent() {
        System.out.println("我是BaseRadio裏的");
    }

    @Override
    public void sent(int s) {
        System.out.println("我是BaseRadio裏的");
    }

    @Override
    public int sent(String a) {
        System.out.println("我是BaseRadio裏的");
        return 0;
    }

    @Override
    public void sent(String a, String b) {
        System.out.println("我是Radio裏的!!!!!");
    }

    @Override
    public void close() {
        System.out.println(port + 2);
        System.out.println("我是TestRadio重寫的");
    }

    public static void main(String[] args) {
        TestRadio testRadio = new TestRadio();
        System.out.println("調用實現類覆蓋的default方法,經過了2次覆蓋,已經和原來完全不同了:");
        testRadio.close();
        System.out.println("實現類調用BaseRadio接口的default方法,就好像自己的方法哦:");
        testRadio.open();

        System.out.println("打印接口裏聲明的port:" + TestRadio.port);
        Radio.prt();
        System.out.println("調用接口的靜態方法");
        BaseRadio.prt();
    }
}

最終輸出如下:

調用實現類覆蓋的default方法,經過了2次覆蓋,已經和原來完全不同了:
9802
我是TestRadio重寫的


實現類調用BaseRadio接口的default方法,就好像自己的方法哦:
打開


打印接口裏聲明的port:9800
uvb76


調用接口的靜態方法
uvb77

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