抽像是物件導向設計的幾大特點之一,在Java中的體現則是抽象類別和介面。這兩者十分的相似,想很多初學者甚至接觸
抽像是物件導向設計的幾大特點之一,在Java中的體現則是抽象類別和介面。這兩者十分的相似,想很多初學者連接觸Java幾年的人也很難分辨他們。今天筆者在查看集合類別相關的程式碼的時候,發現了有部分是介面如List、Map等,有部分是抽象類別如AbstractList、AbstractSet等,由於對兩者不是十分的清楚,比較迷惑。所以今天筆者在本文則主要介紹下這兩者的差異。
抽象類別
抽象方法
利用abstract修飾只有宣告沒有實作的方法,叫做抽象方法。如:
abstract void fun();
抽象類
利用abstract修飾的類,叫做抽象類。如:
abstract class ClassA{}
有抽象方法的類,必須是抽象類別。抽象類別可以沒有抽象方法。抽象類別和普通的類別一樣,可以擁有成員變數和普通的成員方法。
因為抽象類別中含有無具體實作的方法,所以不能用抽象類別建立實例物件!當然可能一個類,只用abstract修飾,但是卻沒有抽象方法,這也屬於抽象類,是不可以實例化的。但是如果要是沒有抽象方法的話為什麼還要設計成抽象類別呢?所以不必去深究。
作用
因此可以看出,抽象類別就是為了繼承而存在的。如果定義了一個抽象類別卻不繼承,那是沒有任何用處的。當然,在繼承之後,之類必須對父類中所有沒有實現的方法進行實現,否則是不被允許的(除非是抽象類繼承的抽象類,此時可以不實現)。
和普通類別的區別
抽象方法必須為public或protected(因為如果為private,則不能被子類別繼承,子類別便無法實現該方法),缺省情況下預設為public。
抽象類別不能用來建立物件;
若子類別繼承抽象類別,則子類別必須實作父類別的抽象方法。否則子類別必須也定義為抽象類別。
在其他方面,抽象類別和普通的類別並沒有區別。
介面
介面是一種極度抽象的類型,它比抽象類別更抽象。介面中可以有變數和方法。但是介面中的變數會被隱含地指定為public static final變數(定義成其他類型,如private會報錯),同時也意味著變數必須進行初始化。介面中的方法會被隱含地指定為public abstract方法(用其他關鍵字,例如private、protected、static、 final等會報錯)。
且介面中所有的方法不能有具體的實現,介面中的方法必須都是抽象方法。
同樣當一個非抽象類別實作了介面的話,必須實作全部方法。否則該類別必須是抽象類,或是介面。
抽象類別和介面比較
語法層面上的區別
介面只能有public abstract 方法,抽象類別的方法類型較多,可以有普通方法;
介面中的成員變數只能是public static final型別類型的,抽象類別的變數類型更多,可以有普通變數;
介面中不能含有靜態程式碼區塊以及靜態方法,而抽象類別可以有靜態程式碼區塊和靜態方法;
一個類別只能繼承一個抽象類別,而一個類別卻可以實作多個介面。
設計層面的差異
1)抽象類別是對事物的抽象(類別的抽象),介面是對行為的抽象。
例如定義Bird是一個抽象類,實現它的有各種鳥類。定義一個介面是fly,各種鳥類可以實現這個介面。通俗來說:繼承是一個 「是不是」的關係,而 介面 實作則是 「有沒有」的關係。鳥類繼承了Bird,那就注定它的種類,而至於是否實現fly接口,只是覺得它是否擁有這項特點(行為)。
2)抽象類別是一種模板式設計,介面是一種行為規範,一種輻射式設計。
例如對於同一個方法,透過抽象類別模板式設計後,當修改此方法時,只需要在模板中修改,所有子類別均可更新;透過介面輻射式設計後,當修改此方法時,需要在所有實作類別中進行修改,才可以更新,互相獨立的。
兩者使用上的聯繫
1.介面若繼承,則必須繼承介面。不能實現。不能繼承抽象類別
2.抽象類別 可以實作接口,可以繼承抽象類,不能繼承介面