面嚮物件語言概論 (一) (轉)

gugu99發表於2007-12-10
面嚮物件語言概論 (一) (轉)[@more@]

面向語言概論 :namespace prefix = o ns = "urn:schemas--com::office" />

(譯自Martin Abadi, Luca Cardelli的物件理論一書的第一部分)

譯者前言

這本書是我們上物件導向型別理論的教材。當時上這門課時,心裡滿不以為然,覺得自己的C++和OO已經頗有造紙,C++和的型別不說倒背如流,也是輕車熟路,上這麼一門課不是白拿學分?哈哈!

但一上起來,才發現自己竟如井底之蛙一樣。老天,原來就這麼簡單的物件導向竟有這麼多說道!原來除了C++, Java, 物件導向還有這麼多沒見過甚至沒想過的東西!

前幾章概論,勉強還都搞定了。但後面上到型別系統的建模,subject reduction的證明,就發現自己就象回到了本科時代,這,這,這怎麼都是數學啊!

這兩天心血來潮。就想把它翻譯一下。後面艱深的地方自覺功力太淺,就不不自量力了。不過,倒可以把前面幾章的概論翻譯一下,如果能起到幫助大家開闊眼界的作用,也就沒白費勁。

 

第二章,基於類的面嚮物件語言

基於類的面嚮物件語言是物件導向世界裡的主流。它包括:

Simula, 第一個面嚮物件語言

Smalltalk, 第一個支援動態型別的語言

C++, 它的大部分基於類的特性繼承自Simula.

等等等等。

與基於類的語言相對應的是基於物件的面嚮物件語言。這裡“基於物件”的概念和把叫做基於物件的概念是不同的。這裡的“基於物件”是指一個只以物件為中心,沒有類的概念的語言,類似之類的語言。

 

現在,我們來介紹一下基於類的面嚮物件語言的一些共同特徵。

 

1.類和物件

讓我們先看一個類的定義:

class cell is

  var contents: Integer :=0;

  method get(): Integer is

    return self.contents;

  end;

  method set(n:Integer) is

    self.contents := n;

  end;

end;

 

一個類是用來描述所有屬於這個類的物件的共同結構的。這個cell類表示的物件擁有一個叫做contents的整數屬性(attribute),這個屬性被初始化成0。它還描述了兩個操作contents的方法。Get和set. 這兩個方法的內容都是很直觀的。Self變數表示這個物件自己。

 

物件的動態語義可以這樣理解:

一個物件在內部被表示為一個指向一組屬性的指標。任何對這個物件的操作都會經過這個指標操作物件的屬性和方法。而當物件被賦值或被當作引數傳遞的時候,所傳遞的只是指標,這樣一來,同一組屬性就可以被共享。

(注, 有些語言如C++, 明確區分指向屬性組的指標和屬性組本身,而一些其它的語言則隱藏了這種區別)

 

物件可以用new從一個類中例項化。準確地說,new C分配了一組屬性,

 並返回指向這組屬性的指標。這組屬性被賦予了初始值,幷包括了類C所定義的方法的程式碼。

 

下面我們來考慮型別。對一個new C所生成的物件,我們把它的型別記為InstanceTypeOf(c). 一個例子是:

var myCell: InstanceTypeOf(cell) := new cell;

 

這裡,透過引入InstanceTypeOf(cell), 我們開始把class和type區分開來了。我們也可以把cell本身當作是型別,但接下來,你就會發現,那樣做會導致混淆的。

 

 

 

2.方法解析。(Method Lookup)

給出一個方法的o.m(……), 一個由各個語言自己實現的叫做方法解析的過程負責找到正確的方法的程式碼。(譯者按:是不是想起了vtable了?)。

直觀地看,方法的程式碼可以被嵌入各個單個物件中,而且,對於許多物件導向語言,對屬性和方法的相似的語法,也確實給人這種印象。

不過,考慮到節省空間,很少有語言這樣實現。比較普遍的方法是,語言會生成許多method suite, 而這些method suite可以被同一個類的物件們所共享。方法解析過程會延著物件內指向method suite的指標找到方法。

在考慮到繼承的情況,方法解析會更加複雜化。Method suite也許會被組成一個樹,而對一個方法的解析也許要查詢一系列method suite. 而如果有多繼承的話,method suite甚至可能組成有向圖,或者是環。

 

方法解析可能發生在編譯時,也可能發生在執行時。

 

在一些語言中,方法到底是嵌入物件中的,還是存在於method suite中這種細節,對員是無關緊要的。因為,所有能區分這兩種的語言特性一般在基於類的面嚮物件語言中都不被支援。

比如說,方法並不能象屬性一樣從物件中取出來當作使用。方法也不能象屬性一樣在物件中被。(也就是說,你更新了一個物件的方法,而同一個類的其它物件的該方法保持不變。)

 

3. 子類和繼承 (Subclassing and Inheritance

子類和一般的類一樣,也是用來描述物件的結構的。但是,它是透過繼承其它類的結構來漸進式地實現這個目的。

父類的屬性會被隱式地複製到子類,子類也可以新增新的屬性。在一些語言中,子類甚至可以overr父類的屬性(透過更改屬性的型別來實現)

父類中的方法可以被複制到子類,也可以被子類override.

一個子類的程式碼的示例如下:

subclass reCell of cell is

  var backup: Integer := 0;

  override set(n: Integer) is

    self.backup := self.contents;

    super.set(n);

  end;

  method restore() is

    self.contents := self.backup;

  end;

end;

 

對有subclass的方法解析,根據語言是靜態型別還是動態型別而有所不同。

在靜態型別的語言(如C++, Java)裡,父類,子類的method suite的拓撲結構在編譯時就已經確定,所以可以把父類的method suite裡的方法合併到子類的method suite中去,方法解析時就不用再搜尋這個method suite的樹或圖了。(譯者按:C++的vtable就是這種方法)

而對於動態型別的語言,(也就是說,父子類的關係是在執行時決定的),method suite就無法合併了。所以,方法解析時,就要沿著這個動態生成的樹或有向圖搜尋直到找到合適的方法。而如果語言支援多繼承,這個搜尋就更復雜了。

 


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

相關文章