沒能不能,只有肯不肯。
一個軟件的好壞,很大程度上取決于它的整體架構(gòu),整體架構(gòu)其實可以看成對業(yè)務(wù)的一種架構(gòu)框架的抽象,當(dāng)代表邏輯設(shè)計的整體框架做好之后,底層的具體實現(xiàn)只需要考慮完成相應(yīng)算法和一些基礎(chǔ)的業(yè)務(wù)實現(xiàn)就可以了。當(dāng)你需要開發(fā)另一個類似的項目時,以前的抽象框架層說不定可以再次使用。面向?qū)ο笤O(shè)計重要的是對抽象層的復(fù)用,而不是某一代碼塊的復(fù)用。
在面向?qū)ο缶幊讨校?b>抽象是它的一大特征,有兩種抽象類型來體現(xiàn)OOP的抽象:接口和抽象類。它們有太多相似的地方,導(dǎo)致有些人會認為接口和抽象類可以互換,但并不然,接口和抽象類的區(qū)別還是蠻大的。
OOP面向?qū)ο蟮木幊?,如果要提高程序的?fù)用率、可維護性和可擴展性,就要面向接口編程或 面向抽象類編程,把接口和抽象類作為程序抽象架構(gòu)層中的頂端。
接口
接口在設(shè)計的初衷其實是對行為的抽象,在接口中可以定義變量以及方法,變量默認指定為 ? ? ? ? ? ? ?public static final ,方法為抽象方法,默認指定為 public abstract ,不可以有方法的實現(xiàn),由實現(xiàn)該接口的類去實現(xiàn)該方法,并且接口中所有方法必須為抽象方法。從這里看出接口是一種極具抽象的類型,它比抽象類更“抽象”。
抽象類
顧名思義,包含抽象方法的類成為抽象類(但如果一個類中沒有抽象方法,只用abstract修飾類,該類也為抽象類,也不能實例化),正因為抽象類中包含了沒有具體實現(xiàn)的方法,所以抽象類不能實例化。如果一個類繼承了抽象類,就要實現(xiàn)抽象類中所有的抽象方法。包含抽象方法的類成為抽象類,但并不是抽象類中全都是抽象方法,它也可以有成員變量和成員方法。
抽象類和普通類的區(qū)別
1、抽象類不能實例化,也就是不能用來創(chuàng)建對象。
2、抽象類只能用 public 或 protected 來修飾,因為如果用 private,那抽象類就不能被繼承,也就失去了意義,什么也做不了。
3、抽象類被子類繼承后,子類必須實現(xiàn)其所有的抽象方法,如果沒有實現(xiàn)父類的抽象方法,則子類得定義為抽象類。
語法上抽象類和接口的區(qū)別
1、抽象類和接口之間最大的區(qū)別就是抽象類中可以有方法的實現(xiàn),也可以有方法的定義,但接口中只能有方法的定義,不能有方法的具體實現(xiàn)。這是抽象類的優(yōu)點,非常有用。(你給一個抽象類加一個具體實現(xiàn)的方法,那繼承與這個抽象類的子類也就默認擁有了這個具體方法。如果是接口的話,就只能在接口中定義這個新方法,所有實現(xiàn)了這個接口的類就不能通過編譯,只能將每個實現(xiàn)了這個接口的類來實現(xiàn)這個新方法才行,這顯然是Java接口的缺點)在某些情況下抽象類更容易擴展。
2、抽象類的實現(xiàn)只能由繼承于它的子類來給出,所以這就要講Java的單繼承,一個類只能繼承一個抽象類,作為一個抽象工具來說,效能會大打折扣。接口在這方面會比抽象類好很多,Java中一個類可以實現(xiàn)多個接口,從而這個類就具有了多種類型。可以看出接口是一個定義混合類型的理想工具,混合類型表示這個類不僅具有某個主類型的行為,還具有其他類型的行為。
3、接口中不能出現(xiàn)靜態(tài)方法和靜態(tài)代碼塊,抽象類中可以出現(xiàn)靜態(tài)方法和靜態(tài)代碼塊(關(guān)于為什么學(xué)了以后在回答,知道的告知下)。
通過以上幾點,一個經(jīng)典的設(shè)計模式就出來了:聲明類型的工作仍然由接口來承擔(dān),這里我們給出一個抽象類,且實現(xiàn)了這個接口,而具體類可以選擇實現(xiàn)接口,也可以選擇繼承抽象類,在層次結(jié)構(gòu)中,接口是在最頂層,抽象類則在接口的下一層。這兩個抽象類型的優(yōu)點都能有所發(fā)揮,這就是 ?"缺省適配模式"。當(dāng)你只想實現(xiàn)接口中一個或幾個方法,而不想全都實現(xiàn),這個設(shè)計模式能完美解決這個問題。
接口和抽象類本身就是為了被具體類實現(xiàn)或者繼承。如果在實際開發(fā)中,你準備使用具體類來繼承具體類,那你的設(shè)計就有很大問題了。
設(shè)計上接口與抽象類的區(qū)別
抽象類是對事物本身的抽象,接口是對事物行為的抽象。什么意識呢?舉個簡單的例子:人和魚,他們都會游泳,我們可以把人(People類)和魚(Fish類)都單獨設(shè)為一個類,但游泳是一種行為所以可以創(chuàng)建一個接口Swim,里頭有個抽象方法 swim(),然后我們用People類和Fish類實現(xiàn)這個接口,至于程序員、架構(gòu)師或者鯊魚、鯨魚這種不同身份的人和不同種類的魚,只需要繼承于People類或者Fish類就可以了,從這里我們可以看出,繼承是"是不是"的關(guān)系(程序員是不是人),而接口是“有沒有”的關(guān)系(人有沒有游泳的行為)。如果一個類繼承于抽象類,那這個類就是抽象類的種類,而實現(xiàn)接口是“有沒有”的關(guān)系,例如:人是否會游泳?,會游泳就實現(xiàn)這個接口,否則就不實現(xiàn)。
下面給一個網(wǎng)上流傳廣泛的例子:門和警報。門都有close()和open()兩個行為,我們可以分別用抽象類和接口區(qū)定義它。
如果這時需要在門上安裝警報功能,我們提供兩種方案:
1、把三個功能都放進接口中,萬一有個類只需要警報功能,不需要open()和close(),例如警報器,但實現(xiàn)了這個接口后,它三個功能都有了,這樣的設(shè)計顯然是不行的。
2、把三個功能都放進抽象類中,那只要繼承了抽象類的子類都具有了警報的功能,但有的門不具備警報功能,這樣也顯然不行。
因為open()和close()是門的固有行為,警報是附加的行為。不如我們試試把open()和close()放在Door抽象類中,把警報功能單獨放在Alarm接口中,然后設(shè)計一個警報門繼承Door抽象類然后實現(xiàn)Alarm接口。
本文主要參考于:http://www.cnblogs.com/dolphin0520/p/3811437.html
http://blog.csdn.net/xw13106209/article/details/6923556