C++批判系列5--繼承的本質 (轉)

worldblog發表於2007-12-07
C++批判系列5--繼承的本質 (轉)[@more@]

繼承的本質

繼承關係是一種耦合度很高的關係,它與組合及一般化(genericity)一樣,提供了OO中的一種基本方法,用以將不同的組合起來。一個類的例項同時也是那個類的所有的祖先的例項。為了保證面向設計的有效性,我們應該儲存下這種關係的一致性。在子類中的每一次重新定義都應該與在其祖先類中的最初定義進行一致性檢查。子類中應該儲存下其祖先類的需求。如果存在著不能被儲存的需求,就說明了的設計有錯誤,或者是在系統中此處使用繼承是不恰當的。由於繼承是物件導向設計的基礎,所以才會要求有一致性檢測。C++中對於非虛擬過載的實現, 意味著將不會為其進行一致性檢測。C++並沒有提供物件導向設計的這方面的保證。

繼承被分成"語法"繼承和"語義"繼承兩部分。Saake等人將其描述如下:"語法繼承表示為結構或方法定義的繼承,並且因此與程式碼的重複使用(以及重寫被繼承方法的程式碼)聯絡起來。語義繼承表示為對物件語義(即物件自己)的繼承,。這種繼承形式可以從語義的資料模型中被得知,在此它被用於代表在一個應用的若干個角色中出現的一個物件。"[SJE 91]。Saake等人集中研究了繼承的語義形式。透過是行為還是語義的繼承方式的判斷,表示了物件在系統中所扮的角色。
 
然而,Wegner相信程式碼繼承更具有實際的價值。他將語法與語義繼承之間的區別表示為程式碼和行為上的區別[Weg 91](p43)。他認為這樣的劃分不會引起一方與另一方的相容,並且還經常與另一方不一致。Wegner同樣也提出這樣的問題:"應該怎樣抑制對繼承屬性的修改?"程式碼繼承為模組化(modularisation)提供一個基礎。行為繼承則依賴於"is-a"關係。這兩種繼承方式在合適處都十分有用。它們都要求進行一致性的檢測,這與實際上的有意義的繼承密不可分。

看起來在語義保持關係中那些限制最多的形式中,繼承似乎是其中最強的形式;子類應該儲存祖先類中的所有假設。

Meyer [Meyer 96a and 96b]也對繼承技術進行了分類。在他的分類法中,他指出了繼承的12種用法。這些分析也給我們怎麼使用繼承提供了一個很好的判斷標準,如:什麼時候應該使用繼承,什麼時候不應該它。

軟體元件就象七巧板一樣。當我們組裝七巧板時,每一塊板的形狀必須要合適,但更重要地是,最終拼出的影像必須要有意義,能夠被說得通。而將軟體元件組合起來就更困難了。七巧板只是需要將原本是完整的一幅影像重新組合起來。而對軟體元件的組合會得到什麼樣的結果,是我們不可能預見到的。更糟的是,七巧板的每一塊通常是由不同的程式設計師產生的,這樣當整個的系統被組合起來時,對於它們的吻合程度的要求就更高了。

C++中的繼承像是一塊七巧板,所有的板塊都能夠組合在一起,但是編譯器卻沒有辦法檢測最終的結果是否有意義。換句話說,C++僅為類和繼承提供了語法,而非語義。可重用的C++函式庫的緩慢出現,暗示了C++可能會盡可能地不支援可重用性。相反的是,,Eiffel和 Pascal都與函式庫包裝在一起出現。Object Pascal與MacApp應用軟體聯絡非常緊密。Java也從與Java 的耦合中解脫出來,取而代之的是一個包容廣泛的函式庫。Eiffel也同樣是與一個極其全面的函式庫整合在一起,該函式庫甚至比Java的還要大。事實上函式庫的概念已經成為一個優先於Eiffel語言本身的工程,用以對所有在科學中通用的結構進行重新分類,得到一個常用的分類法。[Meyer 94].


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

相關文章