程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 面向對象語言概論(一)

面向對象語言概論(一)

編輯:關於C++

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

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

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

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

第二章,基於類的面向對象語言

基於類的面向對象語言是面向對象世界 裡的主流。它包括:

Simula, 第一個面向對象語言

Smalltalk, 第一個支持動 態類型的語言

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

等等等等。

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

現在,我們 來介紹一下基於類的面向對象語言的一些共同特征。

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)

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

父類的屬性會被隱式地復制到子類,子類也可以添加新的屬性。在一 些語言中,子類甚至可以override父類的屬性(通過更改屬性的類型來實現)

父類中 的方法可以被復制到子類,也可以被子類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就無法合並了。所以,方法解析時,就要沿著這個動態生成的樹或有向圖搜 索直到找到合適的方法。而如果語言支持多繼承,這個搜索就更復雜了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved