物件(object)是類(class)的乙個例項(instance)。如果將物件比作房子,那麼類就是房子的設計圖紙。所以物件導向設計的重點是類的設計,而不是物件的設計。
對於c++程式而言,設計孤立的類是比較容易的,難的是正確設計基類及其派生類。本章僅僅論述「繼承」(inheritance)和「組合」(composition)的概念。
10.1 繼承
如果a是基類,b是a的派生類,那麼b將繼承a的資料和函式。例如:
class a
public:
void func1(void);
void func2(void);
class b : public a
public:
void func3(void);
void func4(void);
main()
b b;
b.func1(); // b從a繼承了函式func1
b.func2(); // b從a繼承了函式func2
b.func3();
b.func4();
這個簡單的示例程式說明了乙個事實:c++的「繼承」特性可以提高程式的可復用性。正因為「繼承」太有用、太容易用,才要防止亂用「繼承」。我們應當給「繼承」立一些使用規則。
l 【規則10-1-2】若在邏輯上b是a的「一種」(a kind of ),則允許b繼承a的功能和屬性。例如男人(man)是人(human)的一種,男孩(boy)是男人的一種。那麼類man可以從類human派生,類boy可以從類man派生。
class human
class man : public human
class boy : public man
u 注意事項
【規則10-1-2】看起來很簡單,但是實際應用時可能會有意外,繼承的概念在程式世界與現實世界並不完全相同。
例如從生物學角度講,鴕鳥(ostrich)是鳥(bird)的一種,按理說類ostrich應該可以從類bird派生。但是鴕鳥不能飛,那麼ostrich::fly是什麼東西?
class bird
public:
virtual void fly(void);
class ostrich : public bird
例如從數學角度講,圓(circle)是一種特殊的橢圓(ellipse),按理說類circle應該可以從類ellipse派生。但是橢圓有長軸和短軸,如果圓繼承了橢圓的長軸和短軸,豈非畫蛇添足?
所以更加嚴格的繼承規則應當是:若在邏輯上b是a的「一種」,並且a的所有功能和屬性對b而言都有意義,則允許b繼承a的功能和屬性。
10.2 組合
l 【規則10-2-1】若在邏輯上a是b的「一部分」(a part of),則不允許b從a派生,而是要用a和其它東西組合出b。
例如眼(eye)、鼻(nose)、口(mouth)、耳(ear)是頭(head)的一部分,所以類head應該由類eye、nose、mouth、ear組合而成,不是派生而成。如示例10-2-1所示。
class eye
;class nose
;class ear
void smell(void)
void eat(void)
void listen(void)
private:
eye m_eye;
nose m_nose;
mouth m_mouth;
ear m_ear;
示例10-2-1 head由eye、nose、mouth、ear組合而成
如果允許head從eye、nose、mouth、ear派生而成,那麼head將自動具有look、 smell、eat、listen這些功能。示例10-2-2十分簡短並且執行正確,但是這種設計方法卻是不對的。
// 功能正確並且**簡潔,但是設計方法不對。
class head : public eye, public nose, public mouth, public ear
示例10-2-2 head從eye、nose、mouth、ear派生而成
乙隻公雞使勁地追打乙隻剛下了蛋的母雞,你知道為什麼嗎?
因為母雞下了鴨蛋。
很多程式設計師經不起「繼承」的**而犯下設計錯誤。「執行正確」的程式不見得是高質量的程式,此處就是乙個例證。
類的繼承與組合
無論是繼承與組合本質上都是把子物件放在新型別中,兩者都是使用建構函式的初始化列表去構造這些子物件。組合中是希望新類的內部具有已存在的類的一些功能的時候使用,而不是希望將已存在類作為它的介面。組合通過嵌入乙個物件以實現新類的功能,而新類使用者看到的將是新定義的類的介面,而不是來自老類的一些介面。比如,...
繼承與組合
題目描述 已知類如下 1 birthdate 生日類 含有 year,month,day 等資料成員 2 teacher 教師類 含有 num,name,等資料成員 3 professor 教授類 含有 教師類和生日類的資料成員 要求 1 通過對teacher和birthdate使用繼承和組合的方式...
繼承與組合
繼承與組合 繼承是實現類重用的重要手段,但繼承有乙個最大的壞處 就是破壞封裝,相比之下,組合也是實現類重用的重要方式,而採用組合方式來實現類重用則能提供更好的封裝性。繼承特點 繼承子類擴充套件,得到父類的屬性和方法。許可權允許的情況,子類可以直接訪問父類的屬性和方法,極大的破壞了封裝的特性 從而造成...