第2 繼承
前面已經(jīng)說過了,繼承至少有2個(gè)語義: 實(shí)現(xiàn)繼承和類型繼承,在說明這兩個(gè)東西之前,我們繼續(xù)來看上面的例子














現(xiàn)在我們看playBWV996這個(gè)消息,BWV996是Bach所寫一個(gè)魯特琴組曲,魯特琴是彈撥樂器,同時(shí)也是和聲樂器(所謂和聲樂器就是可以演奏和聲)。在很多樂器上都有改編的版本,比如魯特琴的近親吉他等等,這個(gè)時(shí)候,我們可以實(shí)現(xiàn)這樣幾個(gè)類

















然后我們可以嘗試以此調(diào)用



最后一個(gè)會(huì)得到一個(gè)messageNotUnderstand的錯(cuò)誤。也就是說,對(duì)于Bass而言由于不能演奏和聲從而不能演奏BMV996(不過這個(gè)世界上能人太多了...哎),我們換到靜態(tài)類型面向?qū)ο笙到y(tǒng)來看。
對(duì)于第一個(gè)方法,playSolo的時(shí)候我們要求的類型是能夠演奏單音的。我們可以寫出來



2

3

對(duì)于第二個(gè)方法,playChord的時(shí)候我們要求的類型是能夠演奏和弦的,我們可以寫出來



2

3

而對(duì)于第三個(gè)方法,playBWV996的時(shí)候我們要求既能演奏和弦也能演奏單音,這個(gè)時(shí)候出現(xiàn)一個(gè)問題,我們?cè)趺刺幚鞩nstrument的繼承關(guān)系?一個(gè)能演奏和弦的樂器是否可以演奏單音(答案是一般而言是的,但是也不排除有一些不是這樣的)?還是我們簡單的寫:



2

或者



2

3

4

5

對(duì)于動(dòng)態(tài)類型簡單的隱性類型約定,顯示的類型系統(tǒng)帶來的一個(gè)副作用就是我們必須處理類型之間的關(guān)系。注意這里是類型之間的關(guān)系,而不是對(duì)象之間的關(guān)系。老莊同志批了很多篇的面向?qū)ο蟮某橄螅嫦驅(qū)ο蟮念愋拖到y(tǒng)以及面向?qū)ο蟮谋倔w論,其實(shí)都在是在類型關(guān)系上折騰,而不是在對(duì)象關(guān)系上折騰。而事實(shí)上面向?qū)ο蟮?STRONG>類型系統(tǒng)并非必然就是靜態(tài)類型系統(tǒng),而我們的類之間的關(guān)系不一定就和類型的關(guān)系相一致。就像上例所示,在Smalltalk里,Lute,Guitar和Bass之間沒有任何的繼承關(guān)系,但是對(duì)于person的3個(gè)消息而言,它們卻是有類型的。
因此老莊所批的,是對(duì)象類型系統(tǒng)的抽象能力,而非面向?qū)ο蟮某橄竽芰ΑU缢陬愋拖到y(tǒng)里所給的例子,那張他認(rèn)為很失敗的面向?qū)ο蟮膱D,其實(shí)可以完全不依賴?yán)^承來實(shí)現(xiàn),而對(duì)這個(gè)類型系統(tǒng)的消費(fèi)者而言,他們能夠以一定的類型的觀點(diǎn),來處理這個(gè)系統(tǒng)的對(duì)象。
而老莊最后一個(gè)結(jié)論:

我的看法是,這句話根本就是詭辯,前面半句的主語是“一個(gè)類型”,后面半句的主語是"OO"...
雖然前半句是對(duì)的,但是換一樣說法可能更好:"所能接受的操作反映了其本質(zhì)",面向?qū)ο蟊旧砭蜎]有說我要做一個(gè)本質(zhì)抽象,這一點(diǎn)在Smalltalk的類型判斷操作上的可能是一個(gè)佐證,Smalltalk用isKindOf來判斷繼承關(guān)系,我們來玩一個(gè)文字游戲,改成俚語就是kinda,也就是"有一點(diǎn),有幾分"的意思,而不是說,“就是”,或者“從分類學(xué)上可證明之類的含義”。我再舉一個(gè)齷齪的例子。


氣球和保險(xiǎn)套,對(duì)于ballon這個(gè)方法而言是一個(gè)類型,都是"有幾分"可以吹起來。但是我怎么定義一個(gè)精確的本質(zhì)?Ballonable?還是MakeFromLatexAndVeryThin?或者簡單說FlexableAndThin?
在繼承這一點(diǎn)上,我想老莊引文中:Elminster的話是從事物的特征與屬性歸納出它的“類型”。恰恰對(duì)于靜態(tài)類型面向?qū)ο笙到y(tǒng)是可行的。如我前文所述,我把一個(gè)object和所有sender的約定(也就是interface),繼承在一起,恰恰就是一個(gè)頗為恰當(dāng)?shù)念愋投x。
而對(duì)于動(dòng)態(tài)類型系統(tǒng)里的面向?qū)ο笳Z言,繼承的也有類型繼承的含義,但是并不是唯一的途徑。用一句我們常說的話,在靜態(tài)類型系統(tǒng)里,類型和類是緊耦合的,動(dòng)態(tài)類型系統(tǒng)中他們的耦合比較松。
從此而觀,所有對(duì)于面向?qū)ο蟮恼軐W(xué)考慮以及本體的思考,對(duì)于動(dòng)態(tài)面向?qū)ο笙到y(tǒng)已經(jīng)不是那么迫切了。而把對(duì)象類型系統(tǒng)的不足歸咎于面向?qū)ο蟮牟蛔悖菜坪跽摀?jù)不足。
OOA/OOD is invented to solve practical problems. So that there is not really an ultimate design that reflects the 本質(zhì) of 類型. The concept of Type is introduced to model the problem-domain "object"s, which can be physical or subjective. Even for a real world concept like Instrument, different people can have tototally different designs in order to solve different problems in different contexts.
Let's focus on static typed OO languages, Inheritence adds coupling between superclass and subclasses; However, during the past 8 years a lot of alternatives have been introduced to avoid this issue if it is causing problems. Composition, for example, and various design patterns.
I don't think the critic of OO paradigm by 老莊 is fair. But I don't think the answer to 老莊's article is "dymanic typed OO language" either.
What do you think?