版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
類、類型、抽象數(shù)據(jù)類型異同值集和值上的操作集,在這個(gè)意義上,它們通用·類型和抽象數(shù)據(jù)類型都是類型。類型沿用歷史理解是基元類型+簡(jiǎn)單結(jié)構(gòu)類型(預(yù)定義),抽象數(shù)據(jù)類型是用戶可以用基本類型構(gòu)造復(fù)雜類型(用戶定義)·類和抽象數(shù)據(jù)類型都是在類型體系結(jié)構(gòu)上定義操作集,類是用戶定義的程序?qū)ο蟮母爬ǔ橄?。程序?qū)ο笫欠庋b的自主的,主動(dòng)實(shí)施類中定義的操作,加工私有數(shù)據(jù)。抽象數(shù)據(jù)類型只說(shuō)明程序?qū)ο蟮念愋?,被?dòng)地接受該類型允許的操作。<對(duì)象名>.<操作名>ADT:VV.OP1抽象數(shù)據(jù)類型的變量(名)類的實(shí)例對(duì)象(名)V是該類型值的引用V是實(shí)例對(duì)象名,不涉及值子類是類的特化,內(nèi)涵增加子類型是類型的子集內(nèi)涵所小,外延都減小引用對(duì)象在不引起歧義情況下,有時(shí)也可稱“對(duì)象引用”為“**對(duì)象”多個(gè)對(duì)象引用可指向一個(gè)相同對(duì)象多個(gè)指向同一對(duì)象的引用實(shí)際產(chǎn)生了對(duì)象共享—如果被引用對(duì)象可變,共享有可能產(chǎn)生不可預(yù)期的效果2對(duì)象共享與對(duì)象復(fù)制對(duì)象引用復(fù)制即產(chǎn)生共享如果想要復(fù)制對(duì)象,而不是共享-使用對(duì)象的clone方法產(chǎn)生新的對(duì)象一個(gè)新對(duì)象,拷貝對(duì)象的屬性值(要求對(duì)象的屬性值外部可訪問(wèn))Polyp=newPoly(;p.terms=this.terms;p.deg=this.deg;returnp;}延伸問(wèn)題:抽象與封裝·利用抽象和封裝提供了新的語(yǔ)言機(jī)制:模塊、包和類,是·模塊或包是封裝一組數(shù)據(jù)(變量和類型)和一函數(shù)的抽象),也是可單獨(dú)編譯的程序單元?!こ绦虬姆庋b就是要分出公有(外界可見)和私有部分,這樣給外界以清晰簡(jiǎn)單的界面,有利于實(shí)施高層語(yǔ)義。數(shù)據(jù)抽象是一種編寫大型程序的方法學(xué),它基于以數(shù)據(jù)和其相關(guān)操作作模塊分解,構(gòu)成抽象數(shù)據(jù)類型,數(shù)據(jù)抽象即按抽象數(shù)據(jù)類型開發(fā)程序的方法學(xué)。傳統(tǒng)語(yǔ)言也可以實(shí)現(xiàn)數(shù)據(jù)抽象,但無(wú)封裝不安全。·抽象數(shù)據(jù)類型是用戶定義的,但其效果和內(nèi)定義類型一樣,可以用來(lái)定義新類型。抽象與封裝第四章面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言對(duì)象的思想最早源于人工智能研究,60年代槽(slot),槽既可以是屬性(數(shù)據(jù))也可以是行為(操作)和(約束)。但最早見諸文獻(xiàn)是sketchpad提到的OO圖形學(xué)(1963)。60年代挪威的Dahl和Nyard為模擬系統(tǒng)研60年代末,美國(guó)猶他大學(xué)AlanKay到Smalltalk語(yǔ)言關(guān)鍵貢獻(xiàn)-語(yǔ)言完全基于Simula的類和消息的概念。-語(yǔ)言沒有固定的語(yǔ)法,語(yǔ)法分析由類本身完成。-引入了繼承和子類的概念。-確定了語(yǔ)言的語(yǔ)法,這使得編譯器能夠產(chǎn)生高效、可執(zhí)行、精煉1980版本(正式發(fā)行版本)-引入了元類的概念。4.1.2用戶界面模型系統(tǒng)工作空間兩種圖形編輯窗SystemSystemTrancrptagainacceptcancelenter¥¥CATEGORIESMENUMESSAGEMENUTEXT用戶就是按瀏覽窗中顯示的模板填寫程序。(1)保留字(2)字面量字符字面量/數(shù)字面量/符號(hào)字面量/數(shù)組字面量(4)變量實(shí)例變量/類變量/臨時(shí)變量/全局變量/匯聚變量/參數(shù)對(duì)象選擇子參數(shù)0.3sin消息sin發(fā)向0.3,得sin(0.3)3+4消息‘+′帶參數(shù)4發(fā)向?qū)ο?,得對(duì)象7。100@50消息‘@′帶參數(shù)50發(fā)向?qū)ο?00,得(100,50)雙目,括號(hào)優(yōu)先單目?jī)?yōu)先雙目用關(guān)鍵字(帶有‘:'的選擇子)描述的雙目表達(dá)式,也是自變量在不同時(shí)間可賦以不同對(duì)象,任何表達(dá)式加”數(shù)組第4元素與‘?dāng)?shù)組第4元素與‘foo'同名Displaywhite.(6)控制結(jié)構(gòu)ifTrue:[`真’塊執(zhí)行]ifFalse:[`假’塊執(zhí)行]“可以不出現(xiàn)”ifTrue:[absValue-numbernegated]whileFalse:[listat:indexput:0。(7)消息/方法newBox-selfnew.newBoxshow.Loc←newLoc.titl-newTilt.譯器得到虛映象(Virtualimage),虛映象由字節(jié)代碼中間語(yǔ)言編寫,由Smalltalk虛機(jī)解釋執(zhí)行。相應(yīng)的文件系統(tǒng)管理三種文件:源文件、變更文件、映象文件。由于Smalltalk是交互式的,被編譯的方法在執(zhí)行期間出了問(wèn)題要反應(yīng)到源程序,則要對(duì)映象文件施行反編譯Smalltalk的虛機(jī)是一個(gè)新軟件,它有三個(gè)功能部分:用匯編碼寫出的底層方法實(shí)現(xiàn)·程序設(shè)計(jì)在類的層次上進(jìn)行,由類靜態(tài)(于工作空間指明向類發(fā)出消息)或動(dòng)態(tài)(方法運(yùn)行時(shí))生成實(shí)例對(duì)象。每個(gè)對(duì)象當(dāng)接受某消息并執(zhí)行其方法的消息表達(dá)式時(shí)都是在自向其它對(duì)象發(fā)消息。個(gè)簡(jiǎn)單的Smalltalk程序統(tǒng)計(jì)字母出現(xiàn)頻率為空串”f-Bagnew.“f是Bag的實(shí)例”“父類直到0bject.CisLetter”↑f“返回f中的值”“SmalltalkisaprogrammingLanguagefordevelopingsoluionstobothsimpleandcomplexproblem.”例字頻統(tǒng)計(jì)對(duì)比程序PascalPROGRAMFrequencyBEGINWriteln('enterline');BEGINifisLetter(c)THENBEGINk:=ord(c)-ord('a')+1;END;Write(f[i],‘’)“無(wú)消息模式方法,宜寫算法”|scfk|“定義了四個(gè)臨時(shí)變量”f-Arraynew:26."f是Arrey實(shí)例長(zhǎng)度26"s+Prompterprompt:'enterline'“S是Prompter的實(shí)例,裝輸入字串”k=casciiValuefat:kput:(f].↑fEND.單繼承單繼承,只一個(gè)用于創(chuàng)建實(shí)例,并初始化類實(shí)例變量名類變量名匯集變量名標(biāo)識(shí)符標(biāo)識(shí)符標(biāo)識(shí)符表標(biāo)識(shí)符表標(biāo)識(shí)符類方法:方法1方法2方法n實(shí)例方法:方法1方法2方法nd0B君a家庭財(cái)務(wù)帳目'caseOnHandincomesexpenditures’“建立流水帳本初始為amount(元)”newI“建立流水帳本初始為0(元)”instancemethodincomesat:sourceput;lselftotalReceivedFrom:source)amount“從來(lái)源source接收到的錢數(shù),因而手頭現(xiàn)金增加”.cashOnHand-cashOnHand+amount.“為事由reason支付的錢數(shù),因而手頭現(xiàn)金減少?!眅xpendituresat:reasonput:(selftotalSpentFor:reason)+amount.CashOnHand|“回答當(dāng)前手頭現(xiàn)金”“回答自source收錢總數(shù)”“回答自source收錢總數(shù)”|“回答在reason項(xiàng)上總支出”“回答在reason項(xiàng)上總支出”private“實(shí)例變量初始化”cashOnHand-amount.incomes-Dictionarynew.put:nil.initialBalance:Smalltalkput:nil.initialBalance:HouseholdFinances-FinancealHistoryfor:'rent'.for:'rent'.from;'pay'.NouseholdFinancesspend:78.53HouseholdFinancesreceive:820HouseholdFinancesHouseholdFinancesHouseholdFinancesreceive:22.15spend:135.65from:'interest'.for:'food'.在Smalltalk中,系統(tǒng)支持程序也是作為類掛在0bject之下,包括算術(shù)運(yùn)算、數(shù)據(jù)和控制結(jié)構(gòu)的實(shí)現(xiàn)、輸入/出、隨機(jī)數(shù)生成器等。還有將方法和向其發(fā)消息的對(duì)象聯(lián)結(jié)起來(lái)的對(duì)象.這些對(duì)象統(tǒng)稱環(huán)類的存儲(chǔ)Box8×6素真sendpushpushpushsendsendsend?bü±'amount''self'''show',0selferase.selferase.selfshow實(shí)例對(duì)象的存儲(chǔ)實(shí)例對(duì)象只存放數(shù)據(jù),其存儲(chǔ)格式如下圖:bl0tilt6500@600Apauoμloc.tilt6XYPoint活動(dòng)記錄0蓮tC.dvarB真c.dnameclassvaràc.dname.classclassvara4.2面向?qū)ο蟮陌l(fā)展與概念為什么需要面向?qū)ο?語(yǔ)言的發(fā)展面向?qū)ο蟮幕靖拍钪赜玫膯?wèn)題·實(shí)踐中人們認(rèn)識(shí)到重用已有開發(fā)結(jié)果的重要性,提出了軟件重用的概念—最早的重用單元是子程序,如Fortran的子程序庫(kù)-子程序是純粹的過(guò)程抽象,基于子程序的重用有很大局限性-模塊是更合適的重用單元,因?yàn)槟K可以包裝任何功能,更靈活·重用中有一種常見情況:軟件開發(fā)中遇到的新問(wèn)題常與解決過(guò)的問(wèn)題(可以重用的庫(kù)提供的功能)類似,但又不完全相同-已有模塊的功能與需要有差異,無(wú)法以其“現(xiàn)有”形式直接使用—如果模塊功能的改變只能通過(guò)修改源代碼的方式進(jìn)行,程序員就只能拷·但問(wèn)題是有沒有可以使用的源代碼?常常沒有:-模塊可能是購(gòu)入的,提供商不提供源代碼-模塊可能是過(guò)去的遺產(chǎn),源代碼已經(jīng)丟失或部分缺失模塊和程序組織·通過(guò)模塊定義的抽象數(shù)據(jù)類型是相互獨(dú)立的,不同模塊之間無(wú)任何關(guān)系—而實(shí)際情況中,常常需要定義和使用一些相互有關(guān)的類型,可能需要—變體和聯(lián)合機(jī)制就是為了迎合這方面的需要,但它們沒有類型安全性,且未能提供解決類似問(wèn)題的統(tǒng)一框架,難用于應(yīng)付更復(fù)雜的情況-支持相關(guān)類型,可能給程序的結(jié)構(gòu)組織帶來(lái)新的可能性·如何在抽象數(shù)據(jù)類型的框架中提供這一類功能,也是·面向?qū)ο蟮母拍钤谶@些方面都能發(fā)揮很大的作用面向?qū)ο?Object-Oriented)的方法和程序技術(shù),為基于模塊(一個(gè)類也可以看作一個(gè)模塊)的重用問(wèn)題提供了一條解O0發(fā)展史一組數(shù)據(jù)與關(guān)聯(lián)之上相關(guān)的操作形成一個(gè)對(duì)象。-00并不是從模塊化程序設(shè)計(jì)發(fā)展出來(lái)的,它有自己的發(fā)展歷程-00的思想與模塊化的思想是并行發(fā)展,一直相互影響、相互借鑒概念的鼻祖,其設(shè)計(jì)目標(biāo)是擴(kuò)充Algol60,以更好地支持計(jì)算機(jī)在模擬方面的應(yīng)用。60年代在挪威計(jì)算JohanDahl和KristenNygaard獲得2001年圖靈獎(jiǎng)-O0的三個(gè)基本要素:封裝、繼承和動(dòng)態(tài)方法約束都源于Simula-類的概念源自Simula,其設(shè)計(jì)中提出用類定義把一組操作與一組數(shù)據(jù)的這些重要想法是模塊概念和00的起源00發(fā)展史軟件實(shí)踐也需要O0的思想,并逐漸開發(fā)了相關(guān)的支撐技術(shù),包括:—作用域規(guī)則,開的或者閉的作用域-界面與實(shí)現(xiàn)-透明類型與隱晦類型,訪問(wèn)控制,等等—將計(jì)算功能(子程序)約束于程序里處理的數(shù)據(jù)(結(jié)構(gòu)),使我們?cè)?在一些非常規(guī)的語(yǔ)言(如函數(shù)式語(yǔ)言)里,可以通過(guò)引用的概念提供—常規(guī)語(yǔ)言(如C)引進(jìn)了指向函數(shù)的指針,在實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)程序設(shè)計(jì)繼承和動(dòng)態(tài)約束等被Smalltalk發(fā)展,形成目前00的基本概念框架·程序里以類的方式定義各種數(shù)據(jù)抽象·類可以通過(guò)繼承的方式擴(kuò)充新功能,這樣定義的新類(子類,派生類)自動(dòng)繼承已有類(基類,超類,父類)的功能·對(duì)象是類的實(shí)例,是程序運(yùn)行時(shí)的基本數(shù)據(jù)單元·派生類的對(duì)象也看作是原有基類的對(duì)象,可以當(dāng)作基類的對(duì)象使用(子Liskov代換原理,2008年圖靈獎(jiǎng))類定義了對(duì)象的狀態(tài)成分(數(shù)據(jù)成員)和一組相關(guān)操作(稱為方法)·方法調(diào)用總是針對(duì)某個(gè)對(duì)象進(jìn)行的,將方法調(diào)用看作是給相應(yīng)對(duì)象送一·對(duì)一個(gè)消息執(zhí)行什么方法,由接收消息的對(duì)象的類型確定(根據(jù)該對(duì)象所屬的類確定,這就是動(dòng)態(tài)約束)·計(jì)算,就是一組對(duì)象相互通訊的整體效果(對(duì)計(jì)算的另一種看法)-類也是對(duì)象,通過(guò)給類送new消息的方式要求創(chuàng)建類的實(shí)例-各種控制結(jié)構(gòu)也是通過(guò)消息概念建立的和應(yīng)用方面功不可沒(具體理由見后面討論)。原因:隨后是O0設(shè)計(jì)和基于00的軟件開發(fā)等等·后來(lái)的其他成功語(yǔ)言包括Java,微軟提出C#,等等·出現(xiàn)了一些基于對(duì)象的腳本語(yǔ)言,如Python,Ruby等面向?qū)ο蟪绦蛟O(shè)計(jì)的核心問(wèn)題·代碼重用是基本驅(qū)動(dòng)-提高生產(chǎn)率原有程序語(yǔ)言無(wú)法在原有類型系統(tǒng)進(jìn)行便捷的修改繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言的核心抽象數(shù)據(jù)類型是基礎(chǔ)抽象數(shù)據(jù)類型形成新類型動(dòng)態(tài)束定是重要實(shí)現(xiàn)手段-與誰(shuí)束定(也是多態(tài)問(wèn)題)面向?qū)ο蟪绦蛘Z(yǔ)言設(shè)計(jì)的關(guān)注點(diǎn)-方法,消息-公有、私有與保護(hù)類型-覆蓋方法-多態(tài)引用,抽象方法-構(gòu)造,析構(gòu)-動(dòng)態(tài)束定,靜態(tài)束定·面向?qū)ο蟪绦蛘Z(yǔ)言設(shè)計(jì)的關(guān)注點(diǎn)父類和子類的常見區(qū)別-父類可以定義不能被子類訪問(wèn)的私有變量或方法-子類可以在繼承父類成員的基礎(chǔ)上再添加成員子類可以對(duì)一個(gè)或多個(gè)繼承來(lái)的方法進(jìn)行修改。修改后的方子類對(duì)比子類型的概念把子類看作是子類型(通常),如果D是B-若變量x可以引用B單繼承與多繼承—支持多繼承好嗎?—菱形繼承(共享繼承)面向?qū)ο蟮恼Z(yǔ)言·采用單根的類層次結(jié)構(gòu),還是任意的類層次結(jié)構(gòu)?提供那些繼承方式?-例如C++里提供了三種繼承方式允許多重繼承?還是只允許單繼承?是否提供豐富完善的訪問(wèn)控制機(jī)制?·采用基于繼承的模型,還是基于指派的模型·基于類的模型,還是基于對(duì)象或原型的模型·對(duì)象本身的獨(dú)立性(是否允許不屬于任何一個(gè)類的對(duì)象)類本身是不是對(duì)象?面向?qū)ο蟮恼Z(yǔ)言-C++設(shè)法在支持系統(tǒng)程序設(shè)計(jì)的過(guò)程性語(yǔ)言C-另外的一些語(yǔ)言(如Ada)采用可能很不同的方式支持面向?qū)ο蟮某绦蛟O(shè)計(jì),這里不準(zhǔn)備詳細(xì)介紹采用值模型還是引用模型?!獜谋举|(zhì)上說(shuō),只有采用引用模型才能支持方法的動(dòng)態(tài)約束,因此大多數(shù)面向?qū)ο笳Z(yǔ)言采用引用模型-C++采用值模型,可以創(chuàng)建靜態(tài)對(duì)象或棧對(duì)象,但只有通過(guò)對(duì)象引面向?qū)ο蟮恼Z(yǔ)言·是否允許靜態(tài)對(duì)象或者堆棧對(duì)象(自動(dòng)對(duì)象)?多數(shù)面向?qū)ο笳Z(yǔ)言只支持堆對(duì)象(通過(guò)動(dòng)態(tài)存儲(chǔ)分配創(chuàng)建的對(duì)象)-為在這種環(huán)境下編程,人們開發(fā)了許多利用自動(dòng)對(duì)象的對(duì)象管理技術(shù),如是否依賴自動(dòng)廢料收集建和丟棄對(duì)象,對(duì)象之間常存在復(fù)雜的相互引用關(guān)系,由人來(lái)完成對(duì)象的管理和回收很困難。大多數(shù)00語(yǔ)言都依賴于自動(dòng)存儲(chǔ)回收系統(tǒng)面向?qū)ο蟮恼Z(yǔ)言一些腳本語(yǔ)言也支持面向?qū)ο蟮母拍?。例如,面向?qū)ο蟮恼Z(yǔ)言·人們還提出了許多與面向?qū)ο髾C(jī)制有關(guān)的新想法和模型·許多腳本語(yǔ)言提供了獨(dú)特的面向?qū)ο髾C(jī)制:例如-基于對(duì)象原型(而不是類)的00模型總而言之,雖然今天面向?qū)ο蟮哪P秃驼Z(yǔ)言已成為主流程序設(shè)計(jì)方法和主流程序語(yǔ)言,還正在發(fā)展和研究中-許多語(yǔ)言的00機(jī)制非常復(fù)雜,實(shí)際還不斷提出一些新要求,使一些-如何提供一集足夠強(qiáng)大,而且又簡(jiǎn)潔清晰的機(jī)制支持O0的概念和程序-00語(yǔ)言有關(guān)的理論研究還處在研究與應(yīng)用階段·定義類的語(yǔ)言機(jī)制(語(yǔ)言提供特殊的描述結(jié)構(gòu))·描述或定義對(duì)象的機(jī)制·繼承機(jī)制,描述類之間的繼承關(guān)系??赡芏x繼承關(guān)系的性質(zhì)與對(duì)象交互的機(jī)制(方法調(diào)用,消息傳遞)·初始化新對(duì)象的機(jī)制(最好能自動(dòng)進(jìn)行,避免未初始化就使用的錯(cuò)誤)·類型對(duì)象的動(dòng)態(tài)轉(zhuǎn)換機(jī)制(轉(zhuǎn)換對(duì)一個(gè)具體對(duì)象的觀點(diǎn))·控制類成員的訪問(wèn)權(quán)限的機(jī)制對(duì)象銷毀前的臨終處理機(jī)制(最好能自動(dòng)進(jìn)行)·對(duì)象的存儲(chǔ)管理機(jī)制·運(yùn)行中判斷對(duì)象的類屬關(guān)系的機(jī)制、自反等等4.3面向?qū)ο笳Z(yǔ)言的基本特征與實(shí)現(xiàn)封裝→對(duì)象(數(shù)據(jù)和操作)抽象→繼承→動(dòng)態(tài)束定→可交互性基于類的語(yǔ)言面向?qū)ο笳Z(yǔ)言點(diǎn)00程序,復(fù)習(xí)一下基本00程序的特征·這里看一段定義了幾個(gè)類的C++代碼public:char.*deseription;__listlistnodelistnode__public:prew;prew;next;intval;listnade(){prevval.=0;}_if(prevreturn}ligtnadexif(nextreturn}//theactualdatainanode//constructor=next.=headnode.=this;//pointtoself//defaultvalue==thisllprev--headnode)returnO;Prev;llnextgueceggor==this==headnllnextgueceggor==thisnext,intsingleton(){return(prev=-this);]voidinsertbefore(listnode*newnade){if(Inewnode->singletonO)thrownewlisterr("attempttoinsertnodealreadyonlist");prev->next=newnode;newnode->prev-prev;newnode->next=thig;prev=newnode;___newnode->headnode=___voidreneve({if(singleton())thrownewlisterr("attempttoremovenodenotcurrentlyonlist");prev->next=next;next->prev=prev;prev-next-headnode=this;//pointtoself}“l(fā)istnodeO{//destructorif(Isingleton())}定義一個(gè)list類listnodeheader;_public://noexplicitconstructor//implicitconstructionofrequired;'reagerreturn(header.singleton());了returnheader.successor(;}header.insertbefore(newnode);}i1(!header.singleton())thrownewlisterr("attempttodeletenon-emptylist");}通過(guò)繼承定義queue類。(只是作為示例)specializedconstructpublic://no]listnode*p=head();p->remove();returnp;廣-基本容器類沒有具體數(shù)據(jù)域,不保存具體類判斷謂詞,插入刪除等等-通過(guò)繼承實(shí)現(xiàn)存儲(chǔ)具體類型的元素的具體容器gplistnode*gP-listnode*public:gp-listnodeprev;next;headnode;_predecessorO;successor0;voidinsertbetore(gplistnode*nevnode);voidremoveO;“gplistnode();public:intval;}val=V;}v){v){面向?qū)ο筇卣鞯膶?shí)現(xiàn)實(shí)現(xiàn)面向?qū)ο蟮恼Z(yǔ)言,需要考慮它的幾個(gè)標(biāo)志性特征的實(shí)現(xiàn)封裝是一種靜態(tài)機(jī)制,如C++/Java一類語(yǔ)言的各種訪問(wèn)控制機(jī)制也是靜態(tài)的,都可以通過(guò)在符號(hào)表里記錄信息,在編譯中檢查和處理·方法的實(shí)現(xiàn)與以模塊為類型時(shí)局部子程序的實(shí)現(xiàn)一樣。由于每個(gè)方法調(diào)用有一個(gè)調(diào)用對(duì)象,因此方法需要一個(gè)隱含指針,被調(diào)用時(shí)指向調(diào)用對(duì)象,所有對(duì)該對(duì)象的數(shù)據(jù)成員的訪問(wèn)都通過(guò)這個(gè)指針和靜態(tài)確定的偏移量進(jìn)行許多語(yǔ)言以這一指針作為一個(gè)偽變量,稱為this或者self,通過(guò)這種指針·訪問(wèn)調(diào)用對(duì)象,方式上與通過(guò)指針訪問(wèn)普通結(jié)構(gòu)一樣實(shí)現(xiàn)面向?qū)ο笳Z(yǔ)言的關(guān)鍵是兩個(gè)問(wèn)題:一繼承的實(shí)現(xiàn),使派生類型的對(duì)象能當(dāng)作基類的對(duì)象使用-動(dòng)態(tài)約束的實(shí)現(xiàn),能夠從(作為變量的值或者被變量引用的)對(duì)象出發(fā),找到這個(gè)對(duì)象所屬的類里定義的方法制類似,在加工后的程序里(可執(zhí)行程序里)完全沒有關(guān)于封裝的信息制靜態(tài)域和靜態(tài)方法確定(提出有與其他成員一樣的訪問(wèn)控制)-類的靜態(tài)方法可訪問(wèn)靜態(tài)數(shù)據(jù)成員,其他方法也可以訪問(wèn)靜態(tài)數(shù)據(jù)成員-類對(duì)象可以通過(guò)靜態(tài)數(shù)據(jù)成員交換或者共享信息—靜態(tài)成員是靜態(tài)創(chuàng)建的,其初始化在程序開始執(zhí)行前完成(或者在語(yǔ)言定義的適當(dāng)時(shí)刻完成),只做一次-靜態(tài)成員的初始化中不能調(diào)用類的普通方法(因?yàn)闆]有對(duì)象)靜態(tài)域和靜態(tài)方法靜態(tài)方法相當(dāng)于普通子程序,只是具有類封裝(類作用域)。特-沒有調(diào)用對(duì)象不能引用類定義的普通數(shù)據(jù)成員(如Smalltalk里不能引用實(shí)例變量),只能引用本類的靜態(tài)數(shù)據(jù)成員-通常采用某種基于定義類的語(yǔ)法形式調(diào)用僅有靜態(tài)數(shù)據(jù)成員和靜態(tài)方法的類,相當(dāng)于一個(gè)簡(jiǎn)單模塊-提供模塊的內(nèi)部狀態(tài),可以通過(guò)所提供的方法修改狀態(tài)-不能生成有用的實(shí)例(生成的是空實(shí)例,沒有局部的實(shí)例狀態(tài))-靜態(tài)數(shù)據(jù)成員的靜態(tài)方法的封裝,可能定義內(nèi)部數(shù)據(jù)和操作對(duì)象和繼承:數(shù)據(jù)布局B類的對(duì)象BB類的對(duì)象B類的B類的·對(duì)象的實(shí)際表現(xiàn)就是數(shù)據(jù)成員的存儲(chǔ)正確操作,它們只看屬于B對(duì)象的那部分·D類里的方法既可以使用對(duì)象中的B類數(shù)據(jù)成員,也可以使用對(duì)象里的D類數(shù)據(jù)成員類數(shù)據(jù)成員不能拷貝初始化和終結(jié)處理對(duì)象可能具有任意復(fù)雜的內(nèi)部結(jié)構(gòu)·要求創(chuàng)建對(duì)象的程序段做對(duì)象初始化,需反復(fù)描述,很麻煩,易弄錯(cuò)語(yǔ)言通常都提供了專門的機(jī)制,在子程序,它(們)在對(duì)象的存儲(chǔ)塊里構(gòu)造出所需要的對(duì)象能有多種需要,為此C++/Java等都支持一個(gè)類有多個(gè)不同的構(gòu)造函數(shù)初始化和終結(jié)處理·如果變量采用引用語(yǔ)義,所有(值)對(duì)象都需要顯式創(chuàng)建,有明確的創(chuàng)·如果變量是值,為保證初始化,語(yǔ)言需要對(duì)變量創(chuàng)建提供特殊語(yǔ)義,要·對(duì)象初始化必須按一定的順序進(jìn)行-對(duì)象內(nèi)部的基類部分必須在派生類部分之前完成初始化,因?yàn)榕缮?數(shù)據(jù)成員本身也可能是某個(gè)類的對(duì)象,在執(zhí)行整體對(duì)象的構(gòu)造函數(shù)的-這種構(gòu)造規(guī)則是遞歸的,語(yǔ)言必須嚴(yán)格定義對(duì)象的構(gòu)造順序如果變量采用值語(yǔ)義(例如C++),在進(jìn)入一個(gè)作用域的過(guò)程中,就可能出現(xiàn)許多構(gòu)造函數(shù)調(diào)用—進(jìn)入作用域可能是代價(jià)很大的動(dòng)作初始化和終結(jié)處理在對(duì)象銷毀之前,可能需要做一些最后動(dòng)作(終結(jié)處理),例如釋放對(duì)象所占用的各種資源,維護(hù)有關(guān)狀態(tài)等忘記終結(jié)處理,就可能導(dǎo)致資源流失,或者狀態(tài)破壞語(yǔ)言提供終結(jié)動(dòng)作定義機(jī)制,銷毀對(duì)象前自動(dòng)執(zhí)行所定義動(dòng)作C++采用值語(yǔ)義,終結(jié)動(dòng)作以類的析構(gòu)函數(shù)的形式定義:-類變量是堆棧上的對(duì)象,在其作用域退出時(shí),自動(dòng)調(diào)用它們的終結(jié)動(dòng)作-堆對(duì)象需要顯式釋放,釋放之前恰好應(yīng)該執(zhí)行終結(jié)動(dòng)作,易于處理采用引用語(yǔ)義的語(yǔ)言(如Java),通常并不提供銷毀對(duì)象的顯式操作(以防懸空引用),對(duì)象銷毀由GC自動(dòng)進(jìn)行執(zhí)行終結(jié)動(dòng)作的時(shí)間不可預(yù)計(jì),出現(xiàn)了(時(shí)間和順序的)不確定性-對(duì)象關(guān)聯(lián)和GC靜態(tài)和動(dòng)態(tài)約束的方法根據(jù)變量x的類型(在程序里靜態(tài)定義)確定(靜態(tài)約束)根據(jù)方法調(diào)用時(shí)(被x引用/指向)的當(dāng)前對(duì)象的類型確定(動(dòng)態(tài)約束)-由于x可能引用(指向)B所有O0語(yǔ)言都支持動(dòng)態(tài)方法約束(否則就不是00語(yǔ)言),多數(shù)如C++、Ada等方法),而且以靜態(tài)約束作為默認(rèn)方式。這種設(shè)計(jì)與它的C基礎(chǔ)有關(guān)靜態(tài)約束的實(shí)現(xiàn)·調(diào)用靜態(tài)約束的方法,實(shí)現(xiàn)方式就像是調(diào)用普通子程序(過(guò)程/函-1.首先在變量所屬的類(靜態(tài)已知)里查找(查找符號(hào)表)。如果做下一步所有對(duì)靜態(tài)約束的方法的調(diào)用都可以靜態(tài)(編譯時(shí),一次)處理—運(yùn)行時(shí)的動(dòng)作與一般子程序調(diào)用完全一樣,沒有任何額外運(yùn)行開銷-如果語(yǔ)言允許靜態(tài)約束的方法,采用靜態(tài)約束可以提高效率。靜態(tài)約束的方法還可以做inline處理多態(tài)問(wèn)題-通過(guò)overload機(jī)制而獲得的可歸一化方法(重載)-通過(guò)override機(jī)制而獲得的可歸一化方法(重寫)多態(tài)機(jī)制為表達(dá)復(fù)雜設(shè)計(jì)邏輯提供了簡(jiǎn)化手段-Overload:區(qū)分不同場(chǎng)景來(lái)重載方法,避免一個(gè)方法處理多種場(chǎng)景而導(dǎo)致其邏輯復(fù)雜-Override:讓每個(gè)類根據(jù)其功能要求來(lái)重寫所需要的方法,使用者無(wú)需區(qū)別對(duì)待通過(guò)統(tǒng)一方式即可獲得相應(yīng)的功能基于重載的靜態(tài)多態(tài)一個(gè)方法規(guī)范了類的一種能力隨著功能的擴(kuò)展或演化,這種能力也需要演化來(lái)處理多種不到演化·重載發(fā)生在一個(gè)類內(nèi)部,編譯時(shí)解析方法的多態(tài)性(靜態(tài))}}方法的動(dòng)態(tài)約束作tem,對(duì)所有B類對(duì)象都fun(B&x){...x.tem(...)...}同而不同D覆蓋操作sp后,仍:publicB{能正常地調(diào)用操作tem,而這是00程序設(shè)計(jì)里最重要的東西:這一特征使新類給出的行為擴(kuò)充(或修改)可以自(這個(gè)例子就是)·對(duì)最一般的對(duì)象模型,運(yùn)行中調(diào)用動(dòng)態(tài)約束的方法時(shí)要做一次與編-每個(gè)類需要有一個(gè)運(yùn)行時(shí)表示(把類也作為程序?qū)ο?,類表示中需—每個(gè)對(duì)象里必須保存所屬類的信息(一個(gè)類指針,指向其類)-每個(gè)動(dòng)態(tài)方法調(diào)用都啟動(dòng)一次方法查找。如果找到就調(diào)用,找不到就·這種方式普遍有效,可以處理具有任何動(dòng)態(tài)性質(zhì)的對(duì)象模型,如動(dòng)態(tài)類層次結(jié)構(gòu)構(gòu)造和動(dòng)態(tài)方法更新(修改、添加和刪除)、動(dòng)態(tài)類屬關(guān)系等-查找的時(shí)間開銷依賴于繼承鏈的長(zhǎng)度和繼承鏈上各個(gè)類中方法的個(gè)數(shù)—這種方法的缺點(diǎn)是效率太低。如果所采用的對(duì)象模型在動(dòng)態(tài)特性方面動(dòng)態(tài)約束的實(shí)現(xiàn):受限模型語(yǔ)言(包括Smalltalk)都采用功能強(qiáng)大靈活的對(duì)象模型-這也是早期OO·提高算法效率的最基本途徑是限制要解決的問(wèn)題(對(duì)更特殊一些的問(wèn)題,可能找到效率更高的算法),并設(shè)實(shí)現(xiàn),同時(shí)又能滿足絕大部分實(shí)際O0程序開發(fā)的需要常規(guī)00語(yǔ)言中的對(duì)象模型有如下特性(足以支持常見程序設(shè)計(jì)工·在這種模型里就可以避免動(dòng)態(tài)方法查找,使方法調(diào)用的執(zhí)行效率接近普通的子程序調(diào)用的執(zhí)行效率(C++和Stroustrup的貢獻(xiàn))強(qiáng)類型語(yǔ)言的動(dòng)態(tài)多態(tài)問(wèn)題C++的無(wú)法執(zhí)行的多態(tài)函數(shù)設(shè)父類ellipse子類circle均有求周長(zhǎng)求面積area()函數(shù),有以下主程序:main()}動(dòng)態(tài)約束的實(shí)現(xiàn)·優(yōu)化實(shí)現(xiàn)模型,其中絕大部分工作都能靜態(tài)完成:這是一個(gè)指針表,指針指向本類的對(duì)象需要調(diào)用的方法的代碼體·虛表的指針按方法在類里的順序排列,每個(gè)方法對(duì)應(yīng)于一個(gè)順序下標(biāo)double.viablPviablKb;KMvirtualvirtualvirtoalvirtualwoidvirtualvirtualvirtoalvirtualvoidm(doublen(...動(dòng)態(tài)約束的實(shí)現(xiàn)r1=fr2z=*r1--vtableaddress動(dòng)態(tài)約束的實(shí)現(xiàn)依次填入它的虛表(下標(biāo)從0或者1開始算)·若類D的基類是B,建立D的虛表時(shí)先復(fù)制B的虛表。如D覆蓋了B的某個(gè)(某些)動(dòng)態(tài)約束方法,就用新方法的指針覆蓋虛表里對(duì)應(yīng)的已有指針。若D定義了新的動(dòng)態(tài)約束方法,就將它們classpublic:O;//overrideO;//overridevirtualchar*t(..Bab置bar's上工五五8十vtableCodeforbar“smCodeforbar"ss·如果f指向的對(duì)象是B,那么f->m(.)也會(huì)調(diào)用正確的方法__voidtake_vacation();public:pay_datacompute_pay();employee*scan;for(scan=link;scan!=NULL;scan=scan→link)print_empl();例子分析publicvoidmethodl(){System.outprintlnfoopublicvoidmethod2(){System.outprintlnfoopublicstringtostring(return"foo";publicvoidmethod2(){System.out.println("barFoo[]pity={newBaz(),newBar(),newMumble(),newpublicvoidmethod1(){System.out.println("baz1");}publicreturn}public{publicvoidmethod2(){System.out.println("mumble}Foo()};for(inti=i++){pity[i].method1();pity[i].method2();0;i<pity.length;用5分鐘時(shí)間給出執(zhí)行結(jié)果,注意先梳理類的層次關(guān)系和方法調(diào)用重寫方法執(zhí)行分析表重寫方法執(zhí)行分析表重寫方法執(zhí)行分析表外一個(gè)方法,且混雜著方法的重寫Spam(),newYam()};for(inti=0;iSystem.out.println(food[i]);food[i].a();Ham(),newpublicvoida(){}publicvoidb(){b");b");}publicstringtostring(return"Ham";publicvoidb(){System.out.print("Lambb");publicvoida(){}publicstringtostring(return"Yam";publicvoidb(){System.out.print("Spamb");更復(fù)雜的例子·Lamb繼承了Ham的方法a,a調(diào)用b,但是Lamb重寫了方法b..System.out.print("Hama");b();publicvoidb(){System.out.print("Lambb");}動(dòng)態(tài)約束的實(shí)現(xiàn)重溫受限的對(duì)象模型(對(duì)一般程序設(shè)計(jì)已經(jīng)足夠強(qiáng)大):—類層次結(jié)構(gòu)是靜態(tài)確定的-每個(gè)類里的動(dòng)態(tài)約束方法的個(gè)數(shù)和順序都靜態(tài)確定-構(gòu)造方法表的工作在編譯時(shí)完成-每個(gè)對(duì)象里需要增加一個(gè)指向其類的方法表的指針-每次方法調(diào)用需要多執(zhí)行兩條指令(典型情況),多訪問(wèn)內(nèi)存兩次一般軟件系統(tǒng)(包括系統(tǒng)軟件的絕大部分情況)都可以接受在設(shè)計(jì)和實(shí)現(xiàn)C++語(yǔ)言時(shí)特別希望能夠得到高效的方法計(jì)與演化》里也有討論(通過(guò)幾條指令構(gòu)成的一段“蹦床代碼”,將控制轉(zhuǎn)到實(shí)際應(yīng)該調(diào)用的方法,主要是要解決多重繼承問(wèn)題)虛方法(動(dòng)態(tài)約束方法)的一個(gè)重要缺點(diǎn)是不能做inline處理(在線展開要求靜態(tài)確定被調(diào)用的方法),使編譯器難以進(jìn)行C++希望支持高效的系統(tǒng)程序設(shè)計(jì),認(rèn)為虛方法帶來(lái)的效率損失有時(shí)也是不能容忍的,因此它同時(shí)支持靜態(tài)方法約束接口·有些類雖然沒有層次關(guān)系,但可以有共性行為-它們需要的共性行為包括·對(duì)于不同的幾何類型,這些共性行為的內(nèi)涵解-使用接口,而不是公共父類(因?yàn)闆]什么具體計(jì)算行為可復(fù)用)perimeter=2w+2harea=πr2area=√(s(s-a)(s-b)(s-c))perimeter=a+b+c為不同幾何類型實(shí)現(xiàn)相應(yīng)的方法perimeter和area.目標(biāo):客戶代碼無(wú)需區(qū)分不同的幾何類型-直接獲得任意幾何形狀的面積和周長(zhǎng)-能夠創(chuàng)建數(shù)組來(lái)管理各種可能的幾何對(duì)象-能夠在屏幕上畫出幾何形狀對(duì)一組類共性行為的抽取結(jié)果,使得設(shè)計(jì)規(guī)格和實(shí)現(xiàn)相分離-繼承是一種層次抽象和代碼復(fù)用機(jī)制-接口是一種行為層次抽象,無(wú)關(guān)代碼復(fù)用接口publictypename(typename,...,typename);publictypename(typename,...,typename);Example:publicinterfaceVehicle{publicvoidsetDirection(intdirection);-允許/要求相應(yīng)的類來(lái)實(shí)現(xiàn)相應(yīng)的接口接口的實(shí)現(xiàn)publicclassnameimplementsinterface{{publicBicycle{publicVehicle接口及其實(shí)現(xiàn)舉例//Representscircles.privatedoubleradius;//Constructsanewcirclewiththegivenradius.publiccircle(doubleradius){this.radius=radius;/Returnstheareaofthiscircle.Returnstheperimeterofthiscircle.Returnsperimeter(){perimeter(){Math.PI*radius;2.0*radius;2.0*publicpublicpublicperimeter();}類層次結(jié)構(gòu)和強(qiáng)制轉(zhuǎn)換對(duì)象,這時(shí)的(非變換)自動(dòng)類型barB;但子類指針不能引用基類對(duì)象//ok;referencesthroughqwilluseprefixesofBsdataspaceandvtab//dataandvtableentriesofabar向上強(qiáng)制總是安全的,不會(huì)出問(wèn)題,總可以自動(dòng)進(jìn)行。因?yàn)榕缮惏愃袛?shù)據(jù)成分,因此可以支持基類所有后一個(gè)賦值是編譯時(shí)錯(cuò)誤,派生類指針不能引用基類對(duì)象類層次結(jié)構(gòu)和強(qiáng)制轉(zhuǎn)換·如果用foo類的指針q傳遞一個(gè)對(duì)象,可保證該對(duì)象一定是foo的或它-s=q也是靜態(tài)類型錯(cuò)(不能保證q指向的是bar,賦值不安全)這些條件有時(shí)不成立(下面會(huì)看到,在存在多重繼承時(shí))類層次結(jié)構(gòu)和強(qiáng)制轉(zhuǎn)換·如果q指向的確實(shí)是bar類的對(duì)象,轉(zhuǎn)換將成功,x指向該bar類對(duì)象·如果q指向的不是bar類的對(duì)象,轉(zhuǎn)換失敗,x被賦空指針值0·通過(guò)檢查x的值,可以判斷轉(zhuǎn)換是否成功實(shí)現(xiàn)dynamic_cast,就要求在運(yùn)行中能判斷對(duì)象的類型和類型間關(guān)系的實(shí)現(xiàn)需要在虛表里增加一個(gè)類描述符情況下才按這種方式創(chuàng)建虛表(虛表的形式與沒有類描述符時(shí)不同)類層次結(jié)構(gòu)和強(qiáng)制轉(zhuǎn)換多數(shù)O0語(yǔ)言(如Java等)默認(rèn)支持RTTI,虛表里總保存類描述符·如何描述類型是編譯器的具體實(shí)現(xiàn)問(wèn)題,不必關(guān)心雖然Java的類型轉(zhuǎn)換采用C語(yǔ)言類型轉(zhuǎn)換的描述形式,但功能不同·在牽涉到基本類型時(shí),可能需要做值的轉(zhuǎn)換·在牽涉到類類型時(shí),需要做動(dòng)態(tài)的類型轉(zhuǎn)換合法性檢查-如果發(fā)現(xiàn)錯(cuò)誤,就拋出異常ClassCastException-否則做“非變換類型轉(zhuǎn)換”,把相應(yīng)引用直接當(dāng)作所需的類型的引用·從基本類型值到類類型的合法轉(zhuǎn)換,還需要自動(dòng)構(gòu)造對(duì)象(boxing);從了標(biāo)簽(tag)類型和抽象類型,標(biāo)簽類型只限記錄類型。類的繼承性利用了--無(wú)tagged即一般的ADT,有它是為了類繼承XCoord:Float:=0;--這個(gè)包封裝了三個(gè)子類(型)Radius:Float;typeTriangleisnew
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 全國(guó)卷2025屆高三英語(yǔ)下學(xué)期3月模擬題1含解析
- 2024-2025學(xué)年九年級(jí)物理全冊(cè)第二十一章信息的傳遞21.3廣播電視和移動(dòng)通信同步練習(xí)新版新人教版
- 2024-2025學(xué)年高中地理第五章人地關(guān)系與可持續(xù)發(fā)展2協(xié)調(diào)人地關(guān)系實(shí)現(xiàn)可持續(xù)發(fā)展課時(shí)練習(xí)含解析湘教版必修2
- 2024-2025學(xué)年新教材高中數(shù)學(xué)第一章空間向量與立體幾何1.2空間向量基本定理素養(yǎng)作業(yè)提技能含解析新人教A版選擇性必修第一冊(cè)
- 我是一只小蟲子教案
- 小學(xué)綜合素質(zhì)評(píng)價(jià)總結(jié)10篇
- 網(wǎng)絡(luò)購(gòu)票平臺(tái)服務(wù)協(xié)議
- 網(wǎng)絡(luò)營(yíng)銷咨詢服務(wù)合同
- 辦公自動(dòng)化培訓(xùn)課件2024版:打造高效辦公環(huán)境
- 物流行業(yè)高效配送方案:綠色環(huán)保技術(shù)應(yīng)用
- 2024年護(hù)士職業(yè)心理健康關(guān)注護(hù)士心理健康問(wèn)題和應(yīng)對(duì)方法
- 招標(biāo)代理應(yīng)急響應(yīng)預(yù)案
- 國(guó)開2023秋《人文英語(yǔ)4》期末復(fù)習(xí)寫作練習(xí)參考答案
- 四級(jí)高頻詞匯
- 央國(guó)企信創(chuàng)化與數(shù)字化轉(zhuǎn)型規(guī)劃實(shí)施
- 1.四方埔社區(qū)服務(wù)中心場(chǎng)地管理制度
- 智慧城市治理CIM平臺(tái)建設(shè)方案
- 心肺復(fù)蘇后疾病的病理生理和預(yù)后
- 《餐飲服務(wù)的特點(diǎn)》課件
- 廣州市社會(huì)保險(xiǎn)工傷待遇申請(qǐng)表
- 少兒科學(xué)實(shí)驗(yàn)-直升飛機(jī)
評(píng)論
0/150
提交評(píng)論