什么是介面
類是一種具體的實作,而介面定義了一種規范,介面定義了某一批類所需要遵守的規范,介面不關心這些類的內部狀態資料,也不關心這些類里方法的實作細節,它只規定這批類里必須提供某些方法,
介面體現的是規范和實作分離的設計哲學,
介面的特點
介面的定義:
介面的定義使用interface關鍵字,而不是class關鍵字,語法如下:
[修飾符] interface 介面名 extends 父介面1,父介面2{
}
public abstract interface ISuper extends ITest1,ITest2 {
public static final String name="xiaoming";
public abstract void f1();
}
介面的特性:
* 介面里面所有的屬性只能是靜態常量,默認都是public static final,
* 介面里面所有的方法只能是抽象方法,默認都是public abstract,
* 介面是隱式抽象的,當宣告一個介面的時候,不必使用abstract關鍵字;介面中每一個方法也是隱式抽象的,宣告時同樣不需要public static final 或 public abstract,
* 由于介面定義的是一種規范,因此介面里不能實體化、不能包含構造器和初始化塊定義,
* 在Java 8 中,介面中允許有靜態方法、私有方法,和帶預設實作的抽象方法,
介面的繼承:
- 介面支持多繼承,即一個介面可以有多個直接父介面,多個父介面排在extends關鍵字之后,以英文逗號隔開,
- 繼承的多個介面之間,可以有重復的方法,方法的簽名和回傳值必須完全一樣,
- 和類繼承相似,子介面擴展某個父介面,將會獲得父介面里定義的所有抽象方法、常量Field、內部類和列舉類定義,
類實作介面:
- 類實作介面的語法如下:
[修飾符] class 類名 extends 父類 implements 介面1,介面2{
}
- 一個類可以實作一個或多個介面,使用implements關鍵字,當需要實作多個介面時,多個介面之間以英文逗號隔開,一個類可以繼承一個父類,并同時實作多個介面,implements部分必須放在extends部分之后,一個類可以實作多個介面,這也是Java為單繼承靈活性不足所做的補充,
- 實作介面與繼承父類相似,一樣可以獲得所實作介面里定義的常量Field、抽象方法、內部類和列舉類定義,
- 一個類實作了一個或多個介面之后,這個類必須完全實作這些介面里所定義的全部抽象方法(也就是重寫這些抽象方法);否則,該類將保留從父介面那里繼承到的抽象方法,該類也必須定義成抽象類,
介面和抽象類的區別
介面:介面是把隱式的公共方法和屬性組合起來,封裝成特定功能的一個集合,
抽象類:從子類中發現了公共的東西,泛化出父類,然后子類繼承父類,考慮把實體化沒有任何意義的父類定義為抽象類,
介面和抽象類很像,它們都具有如下特征:
* 介面和抽象類都不能被實體化,它們都位于繼承樹的頂端,用于被其他類實作和繼承,
* 介面和抽象類都可以包含抽象方法,實作介面或繼承抽象類的普通子類都必須實作這些抽象方法,
但介面和抽象類之間的差別也非常大,
語法層面的區別:
* 抽象類可以提供成員方法的實作細節,而介面中只能存在public abstract 方法;
* 抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是public static final型別的;
* 介面中不能含有靜態代碼塊以及靜態方法,而抽象類可以有靜態代碼塊和靜態方法;
* 一個類只能繼承一個抽象類,而一個類卻可以實作多個介面,
概念上的區別:
- 類是對物件的抽象,抽象類是對類的抽象,介面是對行為的抽象,抽象類用于共性,介面用于規范,抽象類是對整個類整體進行抽象,包括屬性、行為,但是介面卻是對類區域(行為)進行抽象,
- 舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性,就是都會飛,那么在設計的時候,可以將飛機設計為一個類Airplane,將鳥設計為一個類Bird,但是不能將“飛行”這個特性也設計為類,因為它只是一個行為特性,并不是對一類事物的抽象描述,此時可以將“飛行”設計為一個介面Fly,包含方法fly( ),然后Airplane和Bird分別根據自己的需要實作Fly這個介面,然后至于有不同種類的飛機,比如戰斗機、民用飛機等直接繼承Airplane即可,對于鳥也是類似的,不同種類的鳥直接繼承Bird類即可,從這里可以看出,繼承是一個 “是不是”的關系,而介面實作則是 “有沒有”的關系,如果一個類繼承了某個抽象類,則子類必定是抽象類的種類,而介面實作則是有沒有、具備不具備的關系,比如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實作這個介面,不能飛行就不實作這個介面,
設計層面上的區別:
- 抽象類作為很多子類的父類,它是一種模板式設計,而介面是一種行為規范,它是一種輻射式設計,
- 什么是模板式設計?最簡單例子,大家都用過ppt里面的模板,如果用模板A設計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它們的公共部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和ppt C進行改動,而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新,也就是說對于抽象類,如果需要添加新的方法,可以直接在抽象類中添加具體的實作,子類可以不進行變更;而對于介面則不行,如果介面進行了變更,則所有實作這個介面的類都必須進行相應的改動,
- 下面看一個網上流傳最廣泛的例子:門和警報的例子:門都有open( )和close( )兩個動作,此時我們可以通過抽象類和介面來定義這個抽象概念:
abstract class Door {
public abstract void open();
public abstract void close();
}
或者:
interface Door {
public abstract void open();
public abstract void close();
}
- 但是現在如果我們需要門具有報警alarm( )的功能,那么該如何實作?下面提供兩種思路:
- 1)將這三個功能都放在抽象類里面,但是這樣一來所有繼承于這個抽象類的子類都具備了報警功能,但是有的門并不一定具備報警功能;
- 2)將這三個功能都放在介面里面,需要用到報警功能的類就需要實作這個介面中的open( )和close( ),也許這個類根本就不具備open( )和close( )這兩個功能,比如火災報警器,
- 從這里可以看出, Door的open() 、close()和alarm()根本就屬于兩個不同范疇內的行為,open()和close()屬于門本身固有的行為特性,而alarm()屬于延伸的附加行為,因此最好的解決辦法是單獨將報警設計為一個介面,包含alarm()行為,Door設計為單獨的一個抽象類,包含open和close兩種行為,再設計一個報警門繼承Door類和實作Alarm介面,
interface Alram {
void alarm();
}
abstract class Door {
abstract void open();
abstract void close();
}
class AlarmDoor extends Door implements Alarm {
void oepn() { //.... }
void close() { //.... }
void alarm() { //.... }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/244116.html
標籤:Java
