• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    OO三步曲之淺析OO的基石(二)

    發布: 2007-5-25 11:48 | 作者: 倪 碩 | 來源: uml中國 | 查看: 41次 | 進入軟件測試論壇討論

    領測軟件測試網 多態,替換原則,對象切割

    多態作為OO中的核心機制之一擁有著豐富的內涵。顧名思義,多態就是一種名稱多種形態的意思。其主要有三種形式:函數多態,對象變量多態,泛型多態。函數多態主要包括函數重載(overload)和改寫(overriding)。泛型多態(genericity)主要是提供了一種創建通用工具的方法,可以在特定的場合將其特化。在這里,我們重點要考量的是對象變量多態。在理解對象變量多態之前,我們首先了解一下OO核心機制之一的替換原則。靜態類型的OOPL的一個特征就是一個變量所包含的值(value)的類型可能并不等于這個變量所聲明的類型,在傳統的編程語言中并不具備這樣的特征,因為我們不可能把聲明為整型的變量賦上字符串的變量值。而替換原則發生作用的情況就隱含的描敘了兩種不同類型所具有的關聯----類型繼承。Barbara Liskov曾經這樣描敘替換原則以及起作用的類型之間的關聯:對于類型為S的每個對象s,存在一個類型為T的對象t,對于根據類型T所定義的所有程序P,如果用對象s替換對象t,程序P的行為保持不變,那么類型S就是類型T的子類型[Liskov 1988]

    在理解了多態以及替換原則后,我們可以繼續深入理解繼承與替換原則相結合所帶來的新的觀點?梢哉f繼承與替換原則的引入影響了幾乎所有的OOPL,包括類型系統,值語義/引用語義,對象內存空間分配等等。下面,我將試圖逐步的撥開其中的各種因果。

    首先考慮,people a; 這樣的代碼在編譯器中將如何實現?可以肯定是首先將把類型people綁定到對象a上,然后必須為對象a分配空間。同時,我們創建people的子類man,由于man IS A people。根據多態以及替換原則,我們當然可以讓對象a保存一個man類型的值(這就是替換原則的表現)。這是一種直觀的描敘,但在編程語言的實現過程中就出現一些困難。我們知道繼承是一種擴展接口與實現的方式,那么我們就很難保證man類型不對people類型做擴展,而一旦做出擴展,我們如何能用存儲people對象的空間去存儲man類型的對象值呢?

    people a;
                man b=new man();
                a=b;


    這樣的代碼將首先把b對象進行切割,然后再存儲到a對象空間去。然而這并不是我們所期望的。那么,為了支持OOP的繼承,多態,替換原則,但卻需要避免對象切割的發生,面對對象a我們將采用何種分配空間模型呢?常用的有下面三種方式:

    1, 只為a分配基類people的存儲空間,不支持對象多態以及替換原則。這樣的模型內存分配緊湊,存儲效率很高。

    2, 分配繼承樹中的最大類對象所需要空間(在這里是man類的對象值空間),這樣的模型簡單,同時可以實現多態和替換原則而避免對象切割問題,但是十分浪費內存空間十分明顯。

    3, 只分配用于保存一個指針所需要的存儲空間,在運行時通過堆來分配對象實際類型所需要的空間大小,這樣也可以實現多態和替換原則而避免對象切割問題。(也就是說a只是一個對象的引用,而不是真實的對象,真實對象的生成必須靠程序員顯式的聲明)。

    對于上面提到的三種內存模型,1和3都被一些程序設計語言所采用。相信說到這里,大家應該開始慢慢明白了。是的,C++作為C語言的繼承者,對于效率的追求迫使它必須采用第一種最小靜態空間分配的方式,由于基于?臻g的程序運行效率要比基于堆空間的程序運行效率高出許多,所以C++允許用?臻g保存對象,但同時也允許堆空間保存對象,可以說C++是采用了1和3兩種相混合的內存模型,而C++中基于1內存模型的對象,也就是說基于棧內存空間的對象是沒有辦法體現多態和替換原則的(請思考一下在C++中什么對象是基于棧的),而基于3內存模型的對象將支持多態和替換原則(又想一想在C++中什么對象是基于堆的)。這里,我們終于可以揭開第一層迷霧了,很多人都知道在C++中只有指針和引用才能支持對象的多態行為,但是為什么會如此?上面做出了最好的解釋。

    Java語言由于設計理念和C++有著很大的區別,它采用的是第3種對象模型,一切對象(除了基本類型對象)都是基于堆分配的。這也是Java語言必須采用虛擬機的原因所在。在C++中很大一部分對象是不需要程序員進行管理的(靜態空間對象),而在Java中,如果不采用虛擬機機制,所有的對象都需要程序員管理,而這樣的開發代價將是巨大而不現實的。這也就揭開了第二層迷霧,當我們在對比C++和Java語言的時候總是為虛擬機是否有其價值而爭論不休,但當你拋開所謂的好與不好的簡單討論,進入到其語言本身的內在對象存儲本質的時候,也許對于各種聲音才會有一個屬于自己的清醒認識。

    讓我們繼續望下走,不同的對象內存分配模型直接影響到其程序設計語言的賦值的含義。在各種編程語言中,賦值可以給出兩種不同的語義解釋:復制語義和指針語義。很明顯,由于C++支持兩種相混合的對象存儲模型(但是默認的存儲方式是棧存儲),所以在C++中默認賦值語義采用的是前者,但C++同時提供了指針語義的功能支持(在拷貝構造函數和=運算符重載中用戶進行自定義)。而在Java中采用的是后者。這也就是我們揭開的最后一道迷霧,不同的對象存儲模型直接導致了不同的賦值語義。

    面向對象的計算模型和可計算性

    編程就是用計算所需要的指令構成一種運算裝置,無論我們的程序設計思想以及程序設計語言如何發展和提高,最終我們所使用的底層計算數學模型并沒有改變。但高級程序設計語言給我們帶來的變革是在其語言環境中構建起了一個全新的,更抽象的虛擬計算模型。Smalltalk語言引入的對象計算模型從根本上改變了以前的傳統計算模型,以前的計算模型突出的是順序計算過程中的機器狀態,而現在的對象計算模型突出的對象之間的協作其計算結果由參加計算的所有的對象的狀態總體構成。而由于對象本身具有自身狀態,我們也可以把一個對象看成是一個小的計算機器。這樣,面向對象的計算模型就演變成了許多小的計算機器的合作計算模型。圖靈機作為計算領域內的根本計算模型,精確的抓住了計算的要點:什么是可計算的,計算時間和空間存儲大小開銷有多大。計算模型清楚的界定了可計算性的范圍,也就界定了哪些問題是可求解,哪些問題是不可求解的。OOP為程序員提供了一種更加抽象和易于理解的新的計算模型,但其本身并沒有超越馮.諾依曼體系所代表的圖靈機數學計算模型。所以我們不能期望OOP能幫助我們解決更多的問題,或者減少運算的復雜度。但OOP卻能幫助我們用一種更容易被我們所理解和接受的方式去描敘和解決現實問題。

    結 束

    這篇文章做為這個系列的第一篇,對于OOP中的許多核心概念和機制進行了有益的討論,作者衷心的希望通過這篇文章能夠讓大家對于OOP有更深入的理解,同時明白OOP作為已經發展將近三十年的程序設計思想,其自身豐富的理論內涵不是單單學習幾門OOPL就可以領悟。最后期望本文能實現了它的初衷---拋磚引玉。

    Reference:

    [D&T 1988] : Type Theories and Object-Oriented programming by Scott Danforth and Chris Tomlinson on ACM Computing Surveys Vol.20 No.1 March 1988

    [Liskov 1988] :Data Abstraction and Hierarchy by Barbara Liskov on Sigplan Notices,23(5),1988

    [C&W 1985] On understanding types,data abstraction,and polymorphism by Cardelli . L and Wegner . P on ACM Computing Surveys Vol.17 No.4 Dec 1985

    [B.S 1991] What is “Object-Oriented programming”?(1991 revised version) by Bjarne Stroustrup AT&T Bell Lab Murray Hill ,New Jersey 07974

    [B.S 1998] 《The C++ programming language (Special Editon)》 by Bjarne Stroustrup Addison Wesley 1998

    [Gamma 1995] 《Design Pattern》by Eric Gamma etc Addison Wesley 1995

    [Booch 94] : 《Object-Oriented Analysis and Design with Application (Sec Editon)》 by Grady Booch Addison Wesley 1994

    [Jams 2000] : 《The Java programming language (Third Editon)》by Ken Arnold, Jams Gosling, David Holmes Addison Wesley 2000

    [Budd 2002]: 《Introduction to Object-Oriented programming (Third Editon)》 by Timothy A.Budd Addison Wesley 2002

    參考書籍:

    《C++程序設計語言》Bjarne Stroustrup著 裘宗燕譯 機械工業出版社 2002年

    《設計模式》Erich Gamma等著 李英軍等譯 機械工業出版社 2000年

    《面向對象軟件開發原理》Anton著 袁兆山等譯 機械工業出版社 2003年

    《面向對象編程導論》Timothy A.Budd著 黃明軍等譯 機械工業出版社 2003年

    《面向對象分析與設計》 Grady Booch著 馮博琴等譯 機械工業出版社 2003年

    《面向對象軟件構造》(英文版.第二版) Bertrand Meyer著 機械工業出版社 2003年

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>