「派生」的前言

2021-05-25 21:15:26 字數 2989 閱讀 6721

前一篇,是《封裝》的尾巴(點我),這一篇,是《派生》的前奏……(突然有一種七八月份的感覺)

8.1.派生

型別和型別之間可以有很多關係,其中「派生」是最重要和最基礎的一種關係。這裡有一道小學語文題。

〖輕鬆一刻〗:做小學題,學型別的派生關係

請照著1和

2中三個詞語的關係,從a、

b、c、

d中選出乙個你認為合適的詞填在劃線處:

1) 人類、白種人、黃種人;

2) 交通工具、小汽車、飛機;

3) 電腦、台式電腦、

_____

備選答案:

a)樟腦;b)

硬碟、c

)拖拉機、

d)筆記本。

除非你堅決認為我說的「筆記本」是紙簿,否則你應該不會選錯。這就是「派生」的基本概念:

b型別是一種特定的

a型別。比如:「白種人是一種特定的人類」,或者「飛機是一種特定的交通工具」。此時可稱

b為「派生類」,

a為「基類」,描述為:

a類派生出

b類,或者

b類繼承自a類。

你需要能夠看得懂以下關係圖:

請注意箭頭的方向:由派生類指向基類,這是當前軟體設計界流行的表示法。用

c++的語法,可以表達為:

code:

class transportation //交通工具類

;  class car : public transportation //小汽車是交通工具的派生類

;  class airplane : public transportation //飛機是交通工具的派生類

;  

先不必太關心語法,只要能看出上面有三個,而不是乙個

class

即可。但有讀者馬上要問了:真的需要把「

car」和「

airplane

」全部設計為

class

嗎?為什麼它們不可以就是「交通工具」這個類的兩個變數?示意為如下**:

code:

class transportation //交通工具類

;  transportation acar; //一輛小汽車

transportation aplane; //一架飛機

這種思路是:我設計了乙個超強的「交通工具類」,它同時具備小汽車和飛機應用的功能,然後當需要時,我希望它是小汽車,它就是小汽車,希望它是飛機,它就是飛機。必須承認,前幾年我坐某航空公司的飛機到北京,飛機降落機場時找不到停機位,於是龐大的鐵鳥在首都機場上四處亂逛,當時我是感覺自己正坐在大巴士上……但這是錯覺!現實中要設計生產一種既可以在市區像qq車一樣四處鑽,又可以騰空而飛的玩意兒,怎麼可能呢?

(有同學不服氣:人家美國的變型金剛就是這樣子的……)

這就是學習「派生」之後,你經常要向自己問的乙個重要問題:你真的需要乙個派生類嗎?比如足球有真皮做的,也有塑膠做的,那麼我們需要「足球(基類)」、「皮足球」和「塑膠足球」三個類嗎?

別輕易說「要」或「不要」……複習一下「什麼是封裝」?封裝乙個類,既需要考慮事物內部的本質不變式,還需要考慮它的使用者是誰。

對於賣體育用品的商店,或者對於買家,通常是不需要將「皮足球」和「塑膠足球」分別定義成乙個類。「皮」或「塑膠」只是足球乙個屬性:材料,我們可以用乙個列舉來作簡單區分。

code:

enum material ;  

class football//乙個為買賣設計的足球類

double getprice() const   

void  setprice(double price);  

private:  

meterial _meterial;  

double _price;        

};  

足球當然還有其它屬性,比如尺寸或顏色等等,都非常適於像這裡的「**」及「材料」一樣,被僅僅當成足球的屬性看待(設計為乙個類的不同成員)。

對於足球的產家就不同了,他需要關心乙個足球如何生產出來,所以可能會為

football

類新增「製作」、「質檢」等等和生產相關函式,而「皮球」和「塑膠球」在這些操作上,可能天差地別,這時分拆成三個類就非常自然:

code:

class football  

;  class leatherfootball : public football  

;  class plasticfootball : public football  

;  

這就回到了「飛機」與「小汽車」無法合二為一的情況了,工廠無法在同一條生產線同時生產真皮球和塑膠球,負責塑膠球的質檢員,最好不要同時也負責真皮球的質檢(當然,當然,我知道資本家可能不這麼想)。當使用者是廠家時,足球

class

就和前面為買賣過程所做的設計大有不同:此時我們希望不同材質的球可以擁有自己的

make

函式,從而可以避免去寫乙個超強的,必然也是超複雜的,無所不能的

make

或qualitytest

函式。

〖危險〗:

不要迷戀「變形金剛」,那只是童年乙個夢…… 每個

c++程式設計師懂得「類」是要設計的……於是乎有些人設計設計再設計,**裡就出現乙個「變形金剛」類。原來他們把所有邏輯全寫到乙個函式或乙個類裡面(變形金剛),然後通過各種開關,各種複雜的邏輯,去區分這個類什麼時候是乙個機械人,什麼時候又是乙隻汽車……

其實,真正的設計,首先是懂得「拆分

」,派生是拆分的方法之一。

當然,也要反覆不管三七二十一,物件稍有區別,就被設計成兩個類,這是一種「過度設計」。但對於初學者,有時候只是懶惰造就了乙個個龐然大物——卻振振有辭:我在設計乙個偉大的變形金剛,請不要拿那種無趣的規則制約我的創造力!

醒醒噢,我們寫的是**,而不是科幻**,請不要把**寫成乙份無人理解的寂寞。

最後提乙個問題:足球的尺寸,通常只需要做為乙個屬性設計,請讀者思考什麼情況下,足球的尺寸也會造成專門設計乙個派生類才更合適?

如果您想與我交流,如下鏈結成為我的好友:

C 繼承與派生(公有派生和私有派生)的概念

層次概念是計算機的重要概念。通過繼承 inheritance 的機制可對類 class 分層,提供型別 子型別的關係。c 通過類派生 class derivation 機制來支援繼承。被繼承的型別稱為基類 base class 或超類 superclass 新產生的類為派生類 derived cla...

派生與繼承 多重派生

1 理解下面的程式,並在 vc 6.0 下執行檢視結果,回答程式後面的問題。class cbase1 cbase1 void print protected int a class cbase2 cbase2 void print protected int b class cderive publ...

Advanced Puppet 系列的前言

在網路上,你能找到大量關於puppet的安裝,配置以及基礎用法的文章和部落格。你在通過一段時間的實戰後,熟練掌握了puppet基礎用法,隨著你管理的集群日益擴大,你的部署邏輯越來越複雜,當你打算使用到一些puppet高階用法時,當你想要對puppet 寫測試用例時,當你希望對puppet進行效能調優...