標籤:java 物件導向編程 interface
物件導向的設計,服用的重點其實應該是抽象層的複用,而不是具體某一個代碼塊的複用。
說到了抽象,就不得不提到Java介面和Java抽象類別了,這也是我這裡想要談論的重點。
Java介面和抽象類別代表的就是抽象類別型,就是我們需要提出的抽象層的具體表現。OOP物件導向編程,如果要提高程式的複用率,增加程式的可維護性,可擴充性,就必須是面向介面編程,面向抽象編程,正確地使用介面,抽象類別這些有用的抽象類別型作為你結構層次上的頂層。
Java介面和Java抽象類別有太多相似的地方,又有太多特別的地方,究竟在什麼地方,才是它們的最佳位置呢?把它比較一下,你就可以發現了。
(1)Java介面和Java抽象類別最大的一個區別,就在於Java抽象類別可以提供某些方法的部分實現,而Java介面不可以(就是interface中只能定義方法,而不能有方法的實現,而在abstract class中則可以既有方法的具體實現,又有沒有具體實現的抽象方法),這大概就是Java抽象類別唯一的優點吧,但這個優點非常有用。如果向一個抽象類別中加入一個新的具體方法時,那麼它所有的子類都一下子得到這個新方法,而Java介面做不到這一點,如果向一個Java介面中加入一個新方法,所有實現這個介面的類就無法成功通過編譯了,因為你必須讓每一個類都再實現這個方法才行,這顯然是Java介面的缺點。也就是說Java的抽象類別比Java的介面跟容易進行擴充。
(2)一個抽象類別的實現只能由這個抽象類別的子類給出,也就是說,這個實現處在抽象類別所定義出的繼承的等級結構中,而由於Java語言單繼承性,所以抽象類別作為類型定義工具的效能就大打折扣。在一點上,Java介面的優勢就出來了,任何一個實現了Java介面所規定的方法的類都可以具有這個介面的類型,而一個類可以實現任意多個Java介面,從而這個類就有了多種類型。(使用抽象類別,那麼繼承這個抽象類別的子類類型就比較單一,因為子類只能單繼承抽象類別;而子類能夠同時實現多個介面,因此類型就比較多。介面和抽象類別都可以定義對象,但是只能用他們的具體實作類別來進行執行個體化。)
(3)Java介面是定義混合類型的理想工具,混合類型表明一個類不僅僅具有某個主類型的行為,而且具有其他的次要行為。
(4)結合(1)、(2)點中抽象類別和Java介面的各自優勢,最經典的設計模式就出來了:宣告類型的工作仍然由Java介面承擔,但是同時給出一個Java抽象類別,且實現了這個介面,而其他同屬於這個抽象類別型的具體類可以選擇實現這個Java介面,也可以選擇繼承這個抽象類別,也就是說在階層中,Java介面在最上面,然後緊跟著抽象類別,這下兩個的最大優點都能發揮到極致了。這個模式就是“預設適配模式”。在Java語言中API中用了這種模式,而且全都遵循一定的命名規範:Abstract + 介面名。(A extends Abstract B implements interface C),那麼A既可以選擇實現(@override)介面interface C中的方法,也可以選擇不實現;既可以選擇實現(@override)抽象類別Abstract B中的方法,也可以選擇不實現)
Java介面和抽象類別的存在就是為了具體類的實現和繼承的,如果你準備寫一個具體類去繼承另一個具體類的話,那你的設計就有很大問題了。Java抽象類別就是為了繼承而存在的,它的抽象方法就是為了強制子類必須去實現的。
淺談Java介面和抽象類別的區別