開(kāi)篇之前先說(shuō)明一下,我和老莊有著不錯(cuò)的私交,他最初寫喪鐘系列的時(shí)候,我是忠實(shí)的擁躉之一,莊兄見(jiàn)我尚有寸尺所長(zhǎng),還在喪鐘系列里引用了我的幾個(gè)觀點(diǎn)。然而最近一段時(shí)間里,我作了這樣幾件事情:





經(jīng)過(guò)種種之后,發(fā)現(xiàn)當(dāng)初所謂鳴OO之喪鐘,實(shí)在是言過(guò)其實(shí)。
--------------------------------------------------------------------------------------------------------------------------------------------------------------
第0 關(guān)于"面向?qū)ο?
既然要為人家敲喪鐘,先要找對(duì)了苦主,不然豈不是白忙活了一場(chǎng)。什么是面向?qū)ο螅窟@個(gè)問(wèn)題太大,我們舉一個(gè)很常見(jiàn)的例子:



























































這個(gè)例子自然很不充分,不過(guò)繼承啊,接口啊,多態(tài)啊,略舉大概,尚可以作為一個(gè)討論的例子。從這個(gè)例子里,我們發(fā)現(xiàn)有這樣一個(gè)事實(shí),就是Person類有兩個(gè)方法


分別表示,需要一個(gè)類型為Instrument的對(duì)象instrument,然后對(duì)他進(jìn)行相應(yīng)的操作,而且,從概念上來(lái)講,第一個(gè)方法,使演奏旋律的,也就是單音,而第二個(gè)方法是演奏和聲的。那么,如果我有一個(gè)類











我們知道,玻璃瓶裝了水也是可以發(fā)出聲音,Mozart可是為玻璃瓶寫過(guò)曲子的,而這里我們卻不能



因?yàn)槲覀冊(cè)跇?gòu)造Person類的時(shí)候,我們的play方法是依賴一個(gè)類型為Instrument的Object,換而言之,我們這里所謂的Object-Oriented其實(shí)稱作Object-with-Type-Oriented的更合適,其實(shí)這類語(yǔ)言有一個(gè)專有名詞,叫做static type object oriented。那Object-Oriented是不是就一定是Static Type Object Oriented的呢?不然,比如在Ruby里,我們可以寫成:


























然后就可以



同樣也可以

在這里,類型可以推演也可以留到runtime檢查,如果是推演的話,在playNote里,由于thing調(diào)用了playNote方法,所以傳進(jìn)來(lái)的對(duì)象必須要刻意接受playNote這個(gè)消息,于是Guitar和GlassBottle都是可以通過(guò),因此我即可以演奏我的Perez 711,也可以敲玻璃瓶。這種方式叫做dynamic type。
那么static type和dynamic type區(qū)別在那呢?static type認(rèn)為,class就是type,type就是class; subclass就是subtyping,subtyping就是subclass(其實(shí)這句不嚴(yán)謹(jǐn),在c++里可以使得subclass不是subtyping,但是java里就沒(méi)辦法了);而dynamic type則認(rèn)為類型和class沒(méi)有關(guān)系,類型取決于一個(gè)對(duì)象能夠接受的消息。
那么哪個(gè)才是面向?qū)ο笾婷材兀窟z憾的說(shuō),static type并不是最初的面向?qū)ο蟆R詫?duì)象作為模塊化的單位,始自Simula 67。但是Simula 67并不是一個(gè)面向?qū)ο笙到y(tǒng),以目前的觀點(diǎn)來(lái)看,充其量是Object-based,第一個(gè)面向?qū)ο笳Z(yǔ)言當(dāng)推Smalltalk,Smalltalk是dynamic type的。不過(guò)Smalltalk不太流行,第一個(gè)大面積流行的面向?qū)ο笳Z(yǔ)言是C++,C++是static type的,正如Lisp是第一個(gè)函數(shù)式編程語(yǔ)言,很多Lisp的特性被當(dāng)作函數(shù)式語(yǔ)言的共有特性(比如表是最重要的數(shù)據(jù)結(jié)構(gòu),輕語(yǔ)法)一樣,所以很多人以為面向?qū)ο缶捅厝皇莝tatic type(比如老莊和我)。對(duì)于面向?qū)ο蟮恼`解,80%來(lái)自C++。也就是說(shuō),80%來(lái)自于static type的面向?qū)ο笙到y(tǒng)。將static type面向?qū)ο髿w咎于整個(gè)面向?qū)ο螅逸厡?shí)在是大而無(wú)當(dāng)言過(guò)其實(shí)。
后面我再一一將老莊所言之OO不當(dāng)之處加以說(shuō)明
所以,將我的文章,改為《敲響靜態(tài)類型OO時(shí)代的喪鐘》,應(yīng)該是更為恰當(dāng)?shù)摹?
剛才跟徐X在MSN上聊,他已經(jīng)基本上答應(yīng)寫一個(gè)《YAST - Yet Another Smalltalk Tutorial》了。大家都有福了!
哈哈!
我也隨便說(shuō)兩句,捧捧場(chǎng),不當(dāng)之處還請(qǐng)各位高人批評(píng)啊。 :)
個(gè)人覺(jué)得《Thinking In Java》的開(kāi)篇:Everything is an Object影響了不少人的思維,至少我當(dāng)年也把Java當(dāng)作是最為純正的OO語(yǔ)言,因?yàn)樽詈?jiǎn)單的Hello,World都必須用上class這樣的高級(jí)的關(guān)鍵字。然而現(xiàn)在看起來(lái),Java所強(qiáng)調(diào)的并不是Object,而是Everything is a Type。
在OO當(dāng)中,Type已經(jīng)被抬得太高了,以致影響了思維。其實(shí)像Python那樣,不把
Class當(dāng)作first class(將function的地位提高至與Class一致)的時(shí)候,當(dāng)繼承只是為了減少代碼復(fù)制的時(shí)候,很多事情都會(huì)變得很簡(jiǎn)單。
還是很喜歡Python的靈活,少掉了很多束縛,卻不失嚴(yán)謹(jǐn)~~
http://www.jot.fm/issues/issue_2003_05/column2
在JVM spec一書中,作者強(qiáng)調(diào):運(yùn)行時(shí)沒(méi)有Type只有Class,所以java對(duì)Type與Class是有區(qū)別的。
在Inside JVM一書中,有言:不采用全反射目的是為了維運(yùn)行 時(shí)護(hù)類型(Class)系統(tǒng)的穩(wěn)定性。