白馬非馬----繼承 (轉)

gugu99發表於2008-06-24
白馬非馬----繼承 (轉)[@more@]

白馬非馬:namespace prefix = o ns = "urn:schemas--com::office" />

  ----繼承

作者:HolyFire

古人云:“白馬非馬”,為何如是說呢。

這裡有個講究,白馬是指一種白色的馬,而非馬裡的馬指的是各種各樣的馬,有黑馬,棕嗎,五花馬等等,這是在顏色上有所區別,馬還有產地,品種等等區別。這裡給了我們一個啟示,各種各樣的馬可以找出很多共同點,稱之為馬,符合這些特點的動物就是馬了,所以這些共同點不能多也不能少,多了不能同用於所有的馬,少了表達不出馬來。要區別一隻馬需要很多資訊,比如一隻黑色的蒙古馬,在這裡,我除了描述一隻馬外,還要指出它是黑色的,產地是蒙古,這裡還沒有加上馬的品種。

我在《芥子須彌-----封裝》裡曾經提及,事物可以劃分成屬性和方法的集合。那麼我們是不是可以對這個集合進行再加工呢,我們只要在裡面加上一點別的什麼,那他就可以變成別的事物了,想象一下在馬的身上加上鹿的角,呵呵呵呵,可笑嗎。那麼我們說一些嚴肅的,知道我們中華民族的圖騰嗎,龍!龍是在蛇的頭上加上鹿的角,身上加上虎的腿腳,尾巴是魚的尾巴,等等。但是不是隨隨便便就能造就龍這樣偉大的象徵的,不好好設計,就會成為畫蛇添足。

雖然是簡單和相加,但也是有不同的方式的。一般來說有兩種方式:關聯和衍生。

關聯:假設原來的類是用一個袋子將屬性和方法包起來,那是用關聯描述了多個類之間的關係,最簡單的情況就是用一個更大的袋子將兩個小袋子包起來,成為一個新的類。這種關聯叫做組合。

衍生:衍生呢就是用一個大的袋子將一個小的袋子與一些屬性和方法包起來,成為一個新的類

 

 

 

 

 A

 

 

 C

 

 

 B

 

 

 

 

a:關聯

 

 

 

 

 A

 

 

 D

 

b:衍生

我還是用C++來表示一下

class A{

//...屬性+方法

};

class B{

//...屬性+方法

};

//關聯後的新類C

class C{

  A a;

  B b;

};

//衍生後的新類D

class D : public A{

//...屬性+方法

};

看起來關聯(組合)比較容易理解,即將類作為一個屬性,然後形成一個新的類,這和原來類的使用沒什麼區別,自己定義的類就是一個型別,這正是封裝要做的。

衍生—在原來的類的基礎上加上一些屬性和方法產生一個新類,看起來新穎誘人,在麵包上灑一些芝麻,吃起來更有香味,不是嗎。

如何好好利用這一方法,就是我要說的----繼承,只要用心去做,麵包也會非常美味。(這裡提及的都是共有繼承也就是class Y: public X;的形式)

上面的方法說起來簡單,要是用好它,不是件容易的事。

首先D和A有相同的部分就是A

第二,D有A沒有的部分

光光這兩點還說明不了繼承的用途

我們加上一個新類E,他也是與類A衍生得來的

class E : public A{

//...屬性+方法

};

這樣我們就清楚一點了,A是D和E的共同點

耶~~~~!我們終於發現這樣做的好處了。

類D和類E有相同的部分A,而這裡A只被處理了一次,也就是說我們可以少處理一個和A一模一樣的工作,如果有許多個類都是從A衍生而來的,那麼我們就發達了,問題是,如何讓更多的類可以與類A衍生得到有用並好用的類。

這裡老祖宗又顯靈了,白馬非馬說的就是這個道理,馬正是這個類A,加上顏色,產地,品種,就可以描述各種各樣的馬了,加上健康等資訊還能說明馬的狀態,如一隻活蹦亂跳的黑色蒙古馬。

在我們的知識裡有很多已知的共同點,碗,瓷器,風,人,花草,我們將他們成為統稱。

我們可以下一個定義了:繼承--就是將事物之間相同和相似的部分歸納出來。

我們來看一下基類A和子類D的關係,可以發現D中含有A,也就是說可以從一個D類的中提取出一個A類的物件來,這種現象就是繼承的向下性,馬可以是白馬,而白馬就不能說成是馬這個種類的代表。表現在C++中如何處理呢。

D d;

A a = d;

這裡將會產成一個A型別的臨時變數,它是由d中類A那部分組成的

[

d的組成

[類A的部分]  --à  臨時變數da;

]

A a = da;

這種現象叫做切片

再看另一種情況

D * d = new D;

A * a = d;

這時候A * a = d;只涉及到指標的賦值,沒有物件的建立,所以不會引起切片,這裡是將d在中的地址儲存在a這個指標裡,而描述指標指向的物件是一個類A的物件。由於,D中關聯A的資訊,C++使得這樣的操作是合法的,也是可以理解的。

我們可以把繼承A的D稱作為A的某個型別,是類A的一種(或者說,D是一個A),就象白馬是一種馬一樣(白馬是一匹馬)。

繼承非常強大,使用它能得到很多好處,但是世界上沒有包治百病的,過分的運用繼承也會帶來麻煩。可以看出繼承是一種靜態的關係,在編譯期間很多東西都定下來了,這也提高了,但是要改變很困難,所以靈活性還不夠,要想清楚,你的目的是什麼,再決定使用關聯還是繼承。

2001/8/15 

丁寧 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1006064/,如需轉載,請註明出處,否則將追究法律責任。

相關文章