類型

類型所屬現代詞,指的是在漢字的意思是指由各特殊的事物或現象抽出來的共通點。

類型type)以及型系統的起源以及研究與發展是獨立於OOP的。早在五十年代的FORTRAN語言編譯器實現中,就已經採用類型系統作為類型檢查的一種手段。廣義的類型一般被定義為一種約束,也就是一種邏輯公式。而在對類型的研究過程中產生多種方法,比如【C&W 1985】等。而代數方法(algebraic approach)是一種非常好的建立類型的形式化規範的方法。代數中的一個類型對應於一系列元素,在它們之上定義代數操作。同時在此基礎上二階λ演算已經被用於繼承和模板所支持的模型。在上面兩種方法中,類型被認為是一系列滿足確定約束條件的元素,更抽象的方式可以把一個類型當作規定一個約束條件,如果我們規定的約束條件越好,相對應的被定義元素的集合就越精密,所以邏輯公式(logical formulas)就成為描敘類型特徵的最合適工具。在這裡,我們不想深入的探究對於類型理論的各種不同的數學模型,我們需要明白的是類型(type)以及類型理論這個在程式語言中經常套用到的概念的內涵是極其豐富的,而其自身理論的發展並非局限於OOP之中,但當兩者相結合的時候就對我們的程式觀產生了巨大的影響。

面向對象設計OOD)中,“歸類”是重要步驟,一個精心設計的類層次結構是則是OOD的重要成果。類的層次和界面定義得好,將造福軟體系統的實現者、維護者和以後的擴展者:他們會驚喜地發現,許多錯綜複雜的關係在清晰的類型層次中不言自明;而失敗的類層次結構則是災難的來源:為了繞過不合理的類型設計帶來的束縛,編碼員不得不把各種能想到的技巧都用了上去【4】——包括強制的類型cast、直接對對象記憶體的訪問等,而這些技巧往往和潛在的bug形影相隨。

在數據結構的歸納和發展中,類型也扮演了重要的角色。ADT的引入是一個里程碑,早期的語言就開始struct(C)、record(Pascal)等複合結構類型為ADT提供支持。ADT是什麼?抽象數據類型。

程式設計語言中,類型的概念由來已久,而其內涵也在不斷發展之中。語言對類型機制更好效率更高的支持成為語言成熟度的標誌。OOP語言對類型的支持機制包括class、interface、inheritance、polymorphism,RTTI,各種cast等,這為編程帶來了許多方便,因為所有概念在語言中都有了對應物。關於OOP語言中類型的形象闡釋,請參見我寫的《漫談程式設計語言的選擇和學習》(發表於《程式設計師》2001年10月刊)和與朋友合譯的《Object Unencapsulated: Eiffel, Java and C++》1.6節。而在泛性程式設計(GP)概念中,所謂“分類學”也就是對類型的一套定義。而模板參數的constraint,則其實是“類型所需符合之類型”,不妨將其與OOP中interface之概念作一對照:一個class需實現某一interface,才可說其屬於(is-a)一定類型。C++中無interface直接對應物【2】,可這樣表述:一個class需公有繼承一個abstract class,則說其屬於(is-a)該abstract class所定義之類型。而constrained genericity中,模板參數需符合某一constraint,該模板才能實例化。在GP和STL的著作中是這樣表述的:模板參數(這是一個類型)叫model,其需符合的constraint(一個更為抽象的類型)叫做concept。對model更多的constraint叫做refinement。所以,concept-model-refinement可以和interface-class-inheritance對照理解。值得指出的是,Eiffel之父Bertrand Meyer在OOP經典著作Object-Oriented Software Construction 2/e中將泛型定義為類型參數化,並認為泛型技術和OOP中的繼承與多態技術並列:泛型描述水平方向的類型關係;而繼承則描述垂直方向上的類型關係。(我在《漫談程式設計語言的選擇與學習》一文中對此有具體闡釋,見《程式設計師》2001年10月刊及http://zmelody.myrice.com/articles/pl.htm)。Bertrand認為泛型方法是經典OOP方法的補充,因此也可納入OOP的範疇。)兩者在實現上的不同是,C++中GP採用的是generative template實現方法,這是用空間換時間的方法,所以大量使用模板的程式常體積較大,但運行速度稍快於對應的OOP版本;而OOP則採用增加間接層的方法,增加了時間開銷。另外還有一點不同: OOP是成熟的設計方法,interface、class、inheritance等都有語言元素直接對應,而GP的許多概念則缺乏語言級支持。

類(class),類型(type),接口(interface)

這三個概念是在OOP中出現頻率最多,也最容易混淆的。而對於這三個概念的澄清也是文章寫作的初衷。讓我們先看看大師們對於這三個概念的描敘----

“The fundamental unit of programming in Java programming language is the class, but the fundamental unit of the object-oriented design is the type.while classes define types,it is very useful and powerful to be able to define a type without defining a class.Interface define types in an abstract form as a collection of methods or other types that form the contract for the type.” 【Jams 2000】。

“In C++,A class is a user definite type”【B.S 1998】。

“A type is a name used to denote a particular interface……An object may have many types,and widely different objects can share a type.Part of an object’s interface may be characterized by one type ,and other parts by other types.Two objects of the same type need only share parts of their interface.Interface can contain other interface as subset.We say that a type is a subtype of another if its interface contain the interface of its supertype.Often we speak of a subtype inheriting the interface of its supertype”【Gamma 1995】

在其中,一共出現了四個概念:類(class),類型(type),接口(interface)以及契約(contract)。這裡我們說到的類型和上面提到的類型有所不同,是狹義的OOP中的類型。為了理解這幾個概念,我先劃分出三個概念域:一個是針對現實世界的,一個是針對特定程式設計范型的(在這裡就是OO設計范型),最後一個是針對編譯器實現的。也就是說,在現實世界中的概念必須有一種手段映射到OO范型中去,而OO范型中的概念也應該在編譯器實現中有相同的概念對應。由此,我們可以這樣說,類是做為現實世界中的概念,而傳統的OOPL都會提供class關鍵字來表示對現實世界模擬的支持。而接口,是作為OO程式設計范型中與類對應的一個概念。在OO設計中,我們所要做的就是針對接口進行設計和編程,而接口的實質含義就是對象之間的一種契約。而類型就是編譯器實現中針對類和接口所定義的對應概念。可以這樣說,類是現實世界中存在的客觀概念,是唯物的。接口是設計人員定義出來的,存在於設計人員心中的概念,是唯心的。而類型是類和接口這兩種概念的編譯器實現的映射概念,也是唯物的。類型主要是用來指導編譯器的類型檢查的謂詞,類是創建現實對象的模板,接口是OO設計中的關鍵概念。這三個概念相互區別(分別位於不同的概念域),又相互聯繫(都是代表相同的概念的不同概念域的映射)。有了上面的理解,我們看看下面最常見的Java語句:

people a=new man();

這代表了什麼?程式設計師向編譯器聲明了一個people類型(type)的對象變數a,而對象變數a本身卻指向了一個man類(class)的實體(而在編譯器中理解是對象變數a指向了一個類型為man的實體)。再讓我們回到【Jams 2000】,其中句子的根本含義我們可以概括如下:聲明一個類或者一個接口都同時向編譯器註冊了一個新的類型,而此類或者接口以及類型都是共享同樣的一個名字。也就是說。編譯器所能理解的全部都是類型,而程式設計師的工作是把現實中的類概念轉化為設計中的接口概念,而編譯器對應於上兩種概念都有直接的支持,那就是一個類聲明或者接口聲明在編譯器的理解來看就是一個類型聲明。但是反過來卻不一定成立。一個類可以有多個接口(一個類完全有可能實現了設計人員的多個契約條件),同時也就可能有多個類型(因為類型不過是接口這個設計域內的概念在編譯器中的實現)。

相關詞條

相關搜尋

熱門詞條

聯絡我們