繼承(inheritance),是類
d 的物件可以使用僅對類
c的物件有效的方法或者屬性的特性,它使得這些方法和屬性就好像是由類
d定義的。這時,
c 是
d 的父類,d是
c 的子類。在繼承結構中,父類的內部細節對於子類是可見的。所以我們通常也可以說通過繼承的**復用是一種「白盒式**復用」。
組合(composition),是通過對現有的物件進行拼裝(組合)產生新的、更複雜的功能。因為在物件之間,各自的內部細節是不可見的,所以我們也說這種方式的**復用是「黑盒式**復用」。
繼承和組合各有各自的優缺點。比如說,對於繼承,我們可以在編譯期靜態地定義其層次結構;因為
oop語 言直接支援繼承特性,使得在技術上來說,繼承直白明了易於使用;而且,我們也可以很容易地修改通過繼承所復用的實現**。但是,我們不能夠在執行期間改變 通過繼承得到的實現**;而且更加不好的是,父類常常會定義一部分子類的表現特徵,使得父類和子類之間的實現**產生相互依賴,也就是所謂的「繼承破壞封裝性」(
inheritance breaks encapsulation
)的說法。**依賴將會導致很多問題,例如通過繼承而來的實現**可能會不適用於新的問題域,從而使得我們需要去重寫父類或者替換掉某些實現**。同時,**之間的依賴關係,限制了程式的靈活性和可復用性。
對比而言,物件的組合是在執行期間通過物件之間的引用動態定義的。組合要求物件互相尊重(
respect
) 對方的介面。不過這樣做下來,因為物件之間只能唯一的通過介面相互作用,物件的封裝性也就得到了良好地維護。同時,在執行期間,任何物件都能夠被替換為其 他相同型別的物件。更好之處在於,因為物件的實現**只和其介面有關係,所以由潛在的**依賴所帶來的問題出現的機會就大大減少了。對於整個系統的設計而 言,使用物件組合將保證各個類能夠被良好的封裝起來,並且保證這些類能夠只負責解決唯一的問題。這就使得類的層次結構能保持比較小的規模而不至於變成難以 控制的龐然大物。在基於物件組合進行設計的系統中,會有更多的物件、更少的類,系統的行為將由物件之間的互動關係來決定。
在理想 的情況下,我們不需要建立新的元件來完成**復用,而只需要通過物件組合的方法來拼裝已存在的元件以獲取新的功能。但這種情況很少會出現,因為在實際情況 中,現有的元件總是顯得不夠,而通過繼承來復用**往往要比通過組合物件要容易得多。所以繼承和組合兩種方法並存於我們的實際軟體開發過程之中。
舉個例子來說,我們通過
array
來實現乙個
stack
類。有兩種方法,第一種是把
stack
作為 array
的乙個子類,也就是通過類繼承的方式來實現這個
stack 類。
class stack extends array
第二個方法是將乙個
array
型別的例項作為
stack
類的乙個屬性,也就是通過物件組合來實現
stack 類。
class stack extends object
在這個例子中,使用組合來實現
stack
類的效果會更好一些。因為這樣
stack
的例項就不用再繼承多餘的
collection
類的方法和屬性了。
物件導向程式設計中的繼承和組合的簡單比較
繼承 inheritance 是類 d 的物件可以使用僅對類 c的物件有效的方法或者屬性的特性,它使得這些方法和屬性就好像是由類 d定義的。這時,c 是 d 的父類,d是 c 的子類。在繼承結構中,父類的內部細節對於子類是可見的。所以我們通常也可以說通過繼承的 復用是一種 白盒式 復用 組合 com...
物件導向程式設計中的多型和繼承
最近在學習c c 中很多程式設計思想其實和c 很相似,都是物件導向的程式設計。但是在c 的學習中,其實我就一直不是很理解繼承和多型。繼承類之間就反映了這樣的關係 當乙個類需要用到另外乙個類的大部分方法和屬性,但又有自己特有的方法和屬性時,就可以使用繼承這一特性。繼承是從已知的類派生成新類的一種方式,...
物件導向程式設計的3種關係 組合,委託和繼承
軟體設計模式中,有很多經典模式,今天從最基本的繼承 組合 委託開始研究 inheritance composition delegation 一 繼承 inheritance 簡單來說,繼承就是在原有類a的基礎上,新建乙個類b,不過新建的類b是在a的基礎上,繼承父類 a 的屬性以及方法。該模式是面相...