C 中繼承與組合的區別

2021-08-28 05:46:26 字數 3880 閱讀 7160

物件和類是

c++中的重要內容,物件

(object)

是類(class)

的乙個例項

(instance)

。物件導向設計的重點是類的設計,而不是物件的設計。對於

c++程式而言,設計孤立的類是比較容易的,難的是正確設計基類及其派生類。這就和「繼承

」(inheritance)和「

組合」(composition)

有重要聯絡了。類的組合和繼承都是軟體重用的重要方式。但二者的概念和用法不同。

繼承描述的是類與類之間的一般與特殊的關係,即如果a是

b的一種,則允許a繼承

b的功能和屬性。例如汽車是交通工具的一種,小汽車是汽車的一種。那麼汽車類可從交通工具類派生,小汽車類可以從汽車類派生。

組合描述的是類與類之間的整體與部分的關係,即如果在邏輯上a是

b的一部分,則允許

a和其他資料成員組合成

b。例如:發動機、車輪、電池、車門、方向盤、底盤都是小汽車的一部分,它們組合成汽車,而不能說發動機是汽車的一種。

class student      //

學生類 …

private:

int num;

string name;

char ***;

int age; };

class date     //

生日類 …

private:

int year;

int month;

int day; };

class graduate: public student     //

研究生類

…private:

date birthday;

float pay; };

graduate類通過繼承,從student類得到了numname***age等資料成員,通過組合,從date類得到了year,month,day等資料成員。繼承是縱向的,組合是橫向的。如果a

是基類,b是

a的派生類,那麼

b將繼承

a的資料和函式。例如:

class a

;class b : public a

;main()

這個簡單的示例程式說明了乙個事實:

c++的「繼承」特性可以提高程式的可復用性。正因為「繼承」太有用、太容易用,才要防止亂用「繼承」。我們應當給「繼承」立一些使用規則。

【規則1】如果類a和類

b毫不相關,不可以為了使

b的功能更多些而讓b繼承

a的功能和屬性。

【規則2】如果類

b 有必要使用

a 的功能,則要分兩種情況考慮: (

1)若在邏輯上b 是

a 的「一種」(

a kind of

),則允許

b 繼承

a 的功能。如男人(

man)是人(

human

)的一種,男孩(

boy)是男人的一種。那麼類

man

可以從類

human

派生,類

boy

可以從類

man

派生。示例程式如下:

class human

;class man : public human

;class boy : public man

;注意事項

看起來很簡單,但是實際應用時可能會有意外,繼承的概念在程式世界與現實世界並不完全相同。

例如從生物學角度講,鴕鳥(

ostrich

)是鳥(

bird

)的一種,按理說類

ostrich

應該可以從類

bird

派生。但是鴕鳥不能飛,那麼

ostrich::fly

是什麼東西?

class bird

;class ostrich : public bird

;例如從數學角度講,圓(

circle

)是一種特殊的橢圓(

ellipse

),按理說類

circle

應該可以從類

ellipse

派生。但是橢圓有長軸和短軸,如果圓繼承了橢圓的長軸和短軸,豈非畫蛇添足?

所以更加嚴格的繼承規則應當是:若在邏輯上ba一種,並且a的所有功能和屬性對b而言都有意義,則允許b繼承a的功能和屬性。

(2)若在邏輯上a是b的「一部分」(a part of),則不允許b從a派生,而是要用

a和其它東西組合出b。

例如眼(

eye)、鼻(

nose

)、口(

mouth

)、耳(

ear)是頭(

head

)的一部分,所以類

head

應該由類

eye、

nose

、mouth

、ear

組合而成,不是派生而成。示例程式如下:

class eye

;class nose

;class mouth

;class ear

;// 正確的設計,雖然**冗長。

class head

void smell(void)

void eat(void)

void listen(void)

private:

eye m_eye;

nose m_nose;

mouth m_mouth;

ear m_ear;

};示例

head

由eye

、nose

、mouth

、ear

組合而成

如果允許

head

從eye

、nose

、mouth

、ear

派生而成,那麼

head

將自動具有

look

、smell

、eat

、listen

這些功能。

// 功能正確並且**簡潔,但是設計方法不對。

class head : public eye, public nose, public mouth, public ear

;上述程式十分簡短並且執行正確,但是這種設計卻是錯誤的。很多程式設計師經不起「繼承」的**而犯下設計錯誤。

「執行正確」的程式不見得是高質量的程式,此處就是乙個例證。

C 中繼承與組合的區別

c 程式開發中,設計孤立的模擬較容易,設計相互關聯的類卻比較難,這其中會涉及到兩個概念,乙個是繼承 inheritance 乙個是組合 composition 因為二者有一定的相似性,往往令程式設計師混淆不清。類的組合和繼承一樣,是軟體重用的重要方式。組合和繼承都是有效地利用已有類的資源。但二者的概...

C 繼承與組合的區別

1 繼承與組合 2 繼承和組合的使用場景 3 繼承和組合的區別 4 繼承和組合的優缺點 1 繼承的優缺點 2 組合的優缺點 c 程式開發中,設計孤立的模擬較容易,設計相互關聯的類卻比較難,這其中會涉及兩個概念,乙個是繼承 inheritance 乙個是組合 composition 因為二者有一定的相...

組合與繼承的區別

組合和繼承都允許在新的類中設定子物件,只是組合是顯式的,繼承是隱式的。繼承關係 is a 關係 組合關係 has a 關係 例如 car表示汽車物件,vehicle表示交通工具物件,tire表示輪胎物件 如何選擇 兩大原則 不要單純地為了實現 的重用而使用繼承,除非兩個類是 is a 的關係,否則不...