Java中,有兩種實現OOP(Object Oriented Programming)編程的方法:抽象,接口。
final(不能被繼承)與abstract(只能被繼承)永遠不能同時修飾類。
一、抽象類
?????? 抽象方法:只有聲明,沒有實現。
?????? 抽象表示:abstract void fun();
?????? 抽象方法必須用abstract修飾。如果一個類含有抽象方法,由此類為抽象類,抽象類必須用abstract修改。
???? 《Java編程思想》中:包含抽象方法的類。但是一個類若不包含抽象方法,用abstract修飾也是抽象類。但是如果一個抽象類中沒有抽象方法,抽象類的設計即沒有意義。
?????? 因為抽象類中無具體方法,所以不能進行實例化。
?????? 所以抽象類是為繼承而生的,如果定義了抽象類而不去繼承它,則創建抽象類的則沒有意義。
????? 定義一個父類,若父類中一個方法在父類中沒有實現的意義,必須通過子類完成各種實現,則可將此方法定義成抽象方法,則這個父類為抽象類。
?????
二、接口
?????? interface
?????? 泛指提供別人調用的方法或者函數。
?????? 對行為的一個抽象。
?????? 接口中可包含變量和方法。變量只能用(默認也是,其他修飾編譯報錯)public static final修飾。方法只能是(默認也是,其他修飾編譯報錯)public abstract修飾。一般不在接口中定義變量。
三、抽象類與類的區別
?????? 1、抽象類不能實例化。
?????? 2、抽象方法必須是protected,public。默認為public。
?????? 3、一個類繼承抽象類,子類必須實現抽象方法;若沒有實現,則必須將子類標記為抽象類。
四、抽象類與接口的區別
?????? 1、語法層面區別:
???????????? 1)抽象類中提供成員方法的實現細節,接口中只能是public abstract修飾,即只能是抽象方法。
???????????? 2)抽象類中成員變量可實現多種權限public private protected final 等,接口中只能用public static final修飾。
???????????? 3)抽象類中可以有靜態方法和靜態代碼塊,接口中不能有靜態方法和靜態代碼塊。
???????????? 4)單繼承多實現。
?????? 2、設計層面區別:
??????????? 1)抽象類是對事物的抽象,即對類抽象;接口是對行為抽象,即局部抽象。
???????????????? 抽象類對整體形為進行抽象,包括形為和屬性。接口只對行為進行抽象。
? ? ? ? ? ? ? ? 例子:舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性,就是都會飛。那么在設計的時候,可以將飛機設計為一個類Airplane,將鳥設計為一個類Bird,但是不能將飛行 這個特性也設計為類,因此它只是一個行為特性,并不是對一類事物的抽象描述。此時可以將 飛行 設計為一個接口Fly,包含方法fly(),然后Airplane和Bird分別根據自己的需要實現Fly這個接口。然后至于有不同種類的飛機,比如戰斗機、民用飛機等直接繼承Airplane即可,對于鳥也是類似的,不同種類的鳥直接繼承Bird類即可。從這里可以看出,繼承是一個"是不是"的關系,而 接口 實現則是"有沒有"的關系。如果一個類繼承了某個抽象類,則子類必定是抽象類的種類,而接口實現則是有沒有、具備不具備的關系,比如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實現這個接口,不能飛行就不實現這個接口。
??????????? 2)抽象類是多個子類的像類,是一種模板式設計;接口是一咱形為規范,是一種輻射式設計。
? ? ? ? ? ? ? ? ? 例子:最簡單例子,大家都用過ppt里面的模板,如果用模板A設計了ppt B和ppt C,ppt B和pptC公共的部分就是模板A了,如果它們的公共部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和pptC進行改動。而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新。也就是說對于抽象類,如果需要添加新的方法,可以直接在抽象類中添加具體的實現,子類可以不進行變更;而對于接口則不行,如果接口進行了變更,則所有實現這個接口的類都必須進行相應的改動。
? ? ? 3、下面看一個網上流傳最廣泛的例子:門和警報的例子:門都有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 {
void open();
void close();
}
class AlarmDoor extends Door implements Alarm {
void oepn() {
//....
}
void close() {
//....
}
void alarm() {
//....
}
}
請尊重作者勞動成果,借鑒原文鏈接:
http://www.cnblogs.com/dolphin0520/p/3811437.html
接口體現一種規范和實現分離的設計,利用接口可充分降低各模塊之間的耦合。基于此原則,很多架構設計理論都倡導"面向接口"編程。例如:簡單工廠模式,命令模式。