面向?qū)ο蠖鄳B(tài)變量_第1頁
面向?qū)ο蠖鄳B(tài)變量_第2頁
面向?qū)ο蠖鄳B(tài)變量_第3頁
面向?qū)ο蠖鄳B(tài)變量_第4頁
面向?qū)ο蠖鄳B(tài)變量_第5頁
已閱讀5頁,還剩75頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

面向?qū)ο蠖鄳B(tài)變量6/7/20231第一頁,共八十頁,編輯于2023年,星期二很少使用賦值,通常是伴隨著函數(shù)或方法調(diào)用,通過數(shù)值和參數(shù)之間的綁定來實現(xiàn)的。實際用法6/7/20232第二頁,共八十頁,編輯于2023年,星期二簡單變量接收器變量反多態(tài)純多態(tài)(多態(tài)方法)多態(tài)變量形式6/7/20233第三頁,共八十頁,編輯于2023年,星期二publicclassSolitaire{ . . staticCardPileallPiles[]; . . publicvoidpaint(Graphicsg){ for(inti=0;i<13;i++) allPiles[].display(g); }}簡單多態(tài)變量6/7/20234第四頁,共八十頁,編輯于2023年,星期二布局管理器LayoutManager是一個接口標準庫為這個接口提供了幾種不同的實現(xiàn)通過調(diào)用繼承自Component類的setLayoutManager方法,將參數(shù)賦值給本地多態(tài)變量實例6/7/20235第五頁,共八十頁,編輯于2023年,星期二多態(tài)變量最常用的場合是作為一個數(shù)值,用來表示正在執(zhí)行的方法內(nèi)部的接收器。隱藏偽變量smalltalk:self,C++,Java,C#:this接收器變量6/7/20236第六頁,共八十頁,編輯于2023年,星期二classThisExample{ publicvoidone(intx){ value=x+4; two(x+3); } privateintvalue; privatevoidtwo(inty){ System.out.println(“Valueis”+(value+y)); }}例6/7/20237第七頁,共八十頁,編輯于2023年,星期二classThisExample{ publicvoidone(intx){

this.value=x+4;

this.two(x+3); } privateintvalue; privatevoidtwo(inty){ System.out.println(“Valueis”+(this.value+y)); }}等價的明確形式6/7/20238第八頁,共八十頁,編輯于2023年,星期二多態(tài)接收器功能的強大之處表現(xiàn)在消息傳遞與改寫相結(jié)合時。這種結(jié)合是軟件框架開發(fā)的關鍵。一般框架系統(tǒng)中的方法分為兩大類:在父類中定義基礎方法,被多個子類所繼承,但不被改寫;父類定義了關于多種活動的方法,但要延遲到子類才實現(xiàn)。

多態(tài)變量在框架中的作用6/7/20239第九頁,共八十頁,編輯于2023年,星期二由于基礎方法被子類所繼承,因此它們可以用于各個子類實例。接收器變量多態(tài)性的展現(xiàn)。當執(zhí)行基礎方法時,接收器實際上保存的是一個子類實例的數(shù)值。當執(zhí)行一個改寫方法時,執(zhí)行的是子類的方法,而不是父類的方法。例6/7/202310第十頁,共八十頁,編輯于2023年,星期二classWindow{ publicvoidrepaint(){

…paint(graphicsContext);… }

abstractpublicvoidpaint(Graphicsg);privateGraphicsgraphicsContext;}classGraphicsWindowextendsWindow{ publicvoidpaint(Graphicsg){ //dotheappropriatepaintingjob }}例6/7/202311第十一頁,共八十頁,編輯于2023年,星期二基礎方法執(zhí)行延遲方法的模式。該結(jié)合允許在不修改原始代碼的條件下,裁剪延遲方法以適應新的形勢。是解決軟件復用問題的關鍵。思考6/7/202312第十二頁,共八十頁,編輯于2023年,星期二向下造型向下造型是處理多態(tài)變量的過程,并且在某種意義上這個過程的取消操作就是替換。能夠?qū)⑵滟x值給一個聲明為子類的變量嗎?該取消多態(tài)賦值的過程,也稱為反多態(tài)。6/7/202313第十三頁,共八十頁,編輯于2023年,星期二其它例常用的數(shù)據(jù)結(jié)構(gòu):集合、堆棧、隊列、列表。容器對象??蓮陀玫能浖M件。將不同的對象放入一個集合,取出時,如何知道對象的類型呢?6/7/202314第十四頁,共八十頁,編輯于2023年,星期二實現(xiàn)機制ChildaChildIf(aVariableinstanceofChild) aChild=(Child)aVariable

6/7/202315第十五頁,共八十頁,編輯于2023年,星期二純多態(tài)多態(tài)方法支持可變參數(shù)的函數(shù)。支持代碼只編寫一次、高級別的抽象以及針對各種情況所需的代碼裁剪。通常是通過給方法的接收器發(fā)送延遲消息來實現(xiàn)這種代碼裁剪的。6/7/202316第十六頁,共八十頁,編輯于2023年,星期二純多態(tài)例關于純多態(tài)的一個簡單實例就是用JAVA語言編寫的StringBuffer類中的append方法。這個方法的參數(shù)聲明為Object類型,因此可以表示任何對象類型。ClassStringbuffer{ Stringappend(Objectvalue){ returnappend(value,toString();}

…}方法toString被延遲實現(xiàn)。6/7/202317第十七頁,共八十頁,編輯于2023年,星期二純多態(tài)例方法toString在子類中得以重定義。toString方法的各種不同版本產(chǎn)生不同的結(jié)果。所以append方法也類似產(chǎn)生了各種不同的結(jié)果。Append;一個定義,多種結(jié)果。6/7/202318第十八頁,共八十頁,編輯于2023年,星期二泛型通過類型的使用提供了一種將類或者函數(shù)參數(shù)化的方法。與通常的函數(shù)參數(shù)一樣,泛型提供了一種無需識別特定數(shù)值的定義算法的方法。第18章泛型6/7/202319第十九頁,共八十頁,編輯于2023年,星期二泛型將名稱定義為類型參數(shù)。在編譯器讀取類描述時,無法知道類型的屬性,但是該類型參數(shù)可以像類型一樣用于類定義內(nèi)部。在將來的某一時刻,會通過具體的類型來匹配這一類型參數(shù),這樣就形成了類的完整聲明。C++支持泛型6/7/202320第二十頁,共八十頁,編輯于2023年,星期二我們先來看看一個只能持有單個對象的類。6/7/202321第二十一頁,共八十頁,編輯于2023年,星期二在JavaSE5之前,我們可以讓這個類直接持有Object類型的對象:6/7/202322第二十二頁,共八十頁,編輯于2023年,星期二有些情況下,我們確實希望容器能夠同時持有多種類型的對象。但是,通常而言,我們只會使用容器來存儲一種類型的對象。泛型的主要目的之一就是用來指定容器要持有什么類型的對象,而且由編譯器來保證類型的正確性。6/7/202323第二十三頁,共八十頁,編輯于2023年,星期二因此,與其使用Object,我們更喜歡暫時不指定類型,而是稍后再決定具體使用什么類型。要達到這個目的,需要使用類型參數(shù),用尖括號括住,放在類名后面。然后在使用這個類的時候,再用實際的類型替換此類型參數(shù)。在下面的例子中,T就是類型參數(shù):6/7/202324第二十四頁,共八十頁,編輯于2023年,星期二6/7/202325第二十五頁,共八十頁,編輯于2023年,星期二現(xiàn)在,當你創(chuàng)建Holder3對象時,必須指明想持有什么類型的對象,將其置于尖括號內(nèi)。就像main()中那樣。然后,你就只能在Holder3中存入該類型(或其子類,因為多態(tài)與泛型不沖突)的對象了。并且,在你從Holder3中取出它持有的對象時,自動地就是正確的類型。

這就是Java泛型的核心概念:告訴編譯器想使用什么類型,然后編譯器幫你處理一切細節(jié)。

6/7/202326第二十六頁,共八十頁,編輯于2023年,星期二泛型接口泛型也可以應用于接口。例如生成器(generator),這是一種專門負責創(chuàng)建對象的類。6/7/202327第二十七頁,共八十頁,編輯于2023年,星期二我們需要IA的doSomething返回的是一個對象這個對象extends于BaseBeanInterfaceIA<TextendsBaseBean>{publicTdoSomething();}classIAImplimplementsIA<ChildBean>{publicChildBeandoSomething(){returnnewChildBean();}}這樣當你調(diào)用這個實現(xiàn)的時候就能明確地得到返回的對象類型

6/7/202328第二十八頁,共八十頁,編輯于2023年,星期二Template<classT>Tmax(Tleft,Tright){ //returnlargestargument if(left<right) returnright; returnleft;}名稱T是一個參數(shù),但是它不同于函數(shù)的兩個參數(shù)。在函數(shù)的代碼體中,T可以用于任何合適的類型。C++模板函數(shù)6/7/202329第二十九頁,共八十頁,編輯于2023年,星期二代碼體功能決定。并非函數(shù)頭強加的本例要求可比較對T的限制?6/7/202330第三十頁,共八十頁,編輯于2023年,星期二Template<classT>classBox{ public: Box(Tinitial):value(initial){}

TgetValue(){returnvalue;} setValue(TnewValue){value=newValue;} private:

Tvalue;};模板類6/7/202331第三十一頁,共八十頁,編輯于2023年,星期二為了創(chuàng)建模板實例,模板參數(shù)必須與具體類型聯(lián)系起來。Box(int)iBox(7);Cout<<iBox.getValue();???iBox.setValue(12);Cout<<iBox.getValue();???參數(shù)必須與接收器的類型相匹配iBox.setValue(3.1415);//ERROR,invalidtype模板類的使用6/7/202332第三十二頁,共八十頁,編輯于2023年,星期二模板類一般用于開發(fā)容器類Template<classT>classList{Public: voidadd(T); TfirstElement(); Tvalue;Private: List<T>*nextElement模板類的應用6/7/202333第三十三頁,共八十頁,編輯于2023年,星期二在不允許改變原有類的情況下,如何將來自兩個或者更多個不同類的元素結(jié)合起來。例如以統(tǒng)一的表示方式來處理。思考?6/7/202334第三十四頁,共八十頁,編輯于2023年,星期二Apple類:使用printOn方法將自身輸出。Orange類:使用writeTo方法將自身輸出。二進制提供希望將Apple對象和Orange對象保存在同一個列表中,并且使用一個多態(tài)函數(shù)將它們輸出。例6/7/202335第三十五頁,共八十頁,編輯于2023年,星期二定義一個公共的父類,具有共同行為ClassFruit{ public: virtualvoidprint(ostream&)=0;//純虛方法};第一步6/7/202336第三十六頁,共八十頁,編輯于2023年,星期二使用模版,創(chuàng)建一個fruitadapter類,將以Apple或者Orange為參數(shù),同時符合水果的定義Template<classT>ClassFruitAdapter:publicFruit{Public: FruitAdapter(T&f):theFruit(f){} T&value(){returntheFruit;} virtualvoidprint(ostream&out){print(theFruit,out);}Public: T&theFruit;}; 第二步6/7/202337第三十七頁,共八十頁,編輯于2023年,星期二使用模版函數(shù)簡化適配器的創(chuàng)建過程Template<classT>Fruit*newFruit(T&f){ returnnewFruitAdapter<T>(f);}; 第三步6/7/202338第三十八頁,共八十頁,編輯于2023年,星期二AppleanApple(“Rome”);OrangeanOrange;List<Fruit*>fruitList;fruitList.insert(newFruit(anApple));fruitList.insert(newFruit(anOrange));List<Fruit*>::iteratorstart=fruitList.begin();List<Fruit*>::iteratorstop=fruitList.end();For(;start!=stop;++start){ Fruit&aFruit=*start;aFruit.print(cout);}最終方案6/7/202339第三十九頁,共八十頁,編輯于2023年,星期二對于一類相似問題的骨架解決方案。通過類的集合形成,類之間緊密結(jié)合,共同實現(xiàn)對問題的可復用解決方案繼承和改寫的強大能力體現(xiàn)最常見的框架Java中的GUI框架Web開發(fā)中的Struts框架第21章框架6/7/202340第四十頁,共八十頁,編輯于2023年,星期二框架開發(fā)的一個重要基礎使用繼承的兩種方式:代碼復用:基本方法,對問題的現(xiàn)存的解決方案。概念復用:特化方法,用于特定應用的解決方案。復用和特化6/7/202341第四十一頁,共八十頁,編輯于2023年,星期二例:雇員排序。高級抽象和低級抽象6/7/202342第四十二頁,共八十頁,編輯于2023年,星期二classEmployee{public: stringname; intsalary; intstartingYear; }雇員類6/7/202343第四十三頁,共八十頁,編輯于2023年,星期二voidsort(Employee*data[],intn){ for(inti=1;i<n;i++){ intj=i-1; while(j>=0&& v[j+1]->startingYear<v[j]->startingYear){ //swapelements Employee*temp=v[j]; v[j]=v[j+1]; v[j+1]=temp; j=j-1; } }}插入排序-根據(jù)工作年份6/7/202344第四十四頁,共八十頁,編輯于2023年,星期二按照薪水排序?按照姓名排序?不再對雇員記錄排序,對一個浮點數(shù)組排序?思考6/7/202345第四十五頁,共八十頁,編輯于2023年,星期二源代碼級的修改。復用的是排序的思想,不是真正的實現(xiàn)。觀察6/7/202346第四十六頁,共八十頁,編輯于2023年,星期二需要源代碼級的修改的地方?元素類型、元素數(shù)目、數(shù)值比較、元素交換。封裝改變OO方案6/7/202347第四十七頁,共八十頁,編輯于2023年,星期二classInsertionSorter{public: voidsort(){ intn=size(); for(inti=1;i<n;i++){ intj=i-1; while(j>=0&&lessThan(j+1,j)){

swap(j,j+1); j=j-1; } } }OO方案-排序框架6/7/202348第四十八頁,共八十頁,編輯于2023年,星期二private: virtualintsize()=0;//abstractmethods virtualbooleanlessThan(inti,intj)=0; virtualvoidswap(inti,intj)=0;}OO方案-排序框架6/7/202349第四十九頁,共八十頁,編輯于2023年,星期二classEmployeeSorter:publicInsertionSorter{public: EmployeeSorter(Employee*d[],intn) {data=d;sze=n;}private: Employee*data[]; intsze=n; virtualintsize(){returnsze;} virtualboollessThan(inti,intj) {returndata[i]->startingYear<data[j]->startingYear;}OO方案-特化6/7/202350第五十頁,共八十頁,編輯于2023年,星期二 virtualvoidswap(inti,intj){ Employee*temp=v[i]; v[i]=v[j]; v[j]=temp; }}OO方案-特化6/7/202351第五十一頁,共八十頁,編輯于2023年,星期二基類不再需要改變。特化子類滿足不同的需求。如:改變?yōu)閷κ杖脒M行排序只需改變子類,無需改變父類對浮點數(shù)進行排序也只需創(chuàng)建一個新的子類,而無需改變父類觀察6/7/202352第五十二頁,共八十頁,編輯于2023年,星期二繼承允許進行高級別算法細節(jié)的封裝還允許在不改變原始代碼的情況下修改或特化這些細節(jié)。繼承6/7/202353第五十三頁,共八十頁,編輯于2023年,星期二框架改變了應用程序(開發(fā)者定義的代碼)與庫代碼之間的關系傳統(tǒng)的應用程序中應用程序特定的代碼定義了程序執(zhí)行的總體流程在框架中控制流是由框架決定的,并且隨應用程序的不同而不同新的應用程序的創(chuàng)建者只需改變供框架調(diào)用的例程即可,而無需改變總體結(jié)構(gòu).框架占主導地位,而應用程序特定的代碼處于次要位置.倒置庫6/7/202354第五十四頁,共八十頁,編輯于2023年,星期二面向?qū)ο笤O計藝術(shù)為應用程序預言將來可能發(fā)生的變化,并對應用程序進行相應的設計做到這點不容易,需要程序員認識到可以通過類似于以前解決問題的方式或者現(xiàn)存軟件系統(tǒng)的方式來解決新問題時,才能夠?qū)⒃搯栴}泛化,使其適合于更廣泛的應用程序象C++,需要程序員區(qū)分哪些方法可以改寫,以及哪些方法不能改寫,這種方式過于僵硬了由于程序員在最初無法預言改寫某個方法的需求預言變化6/7/202355第五十五頁,共八十頁,編輯于2023年,星期二多個代理組成的團體?對象綁定到一起的連接特性?第23章對象互連6/7/202356第五十六頁,共八十頁,編輯于2023年,星期二一種考慮對象互連的方式就是研究可視性和依賴性這兩個概念。可視性描述了關于名稱的特性,通過該名稱句柄可以存取對象,如果對象的名稱是合法的且代表該對象,那么在這個特定環(huán)境下該對象就是可見的。描述可視性的相關術(shù)語還包括標識符的范疇依賴性將兩個對象或者類聯(lián)系起來,在不存在另外一個對象的條件下,如果一個對象的存在無任何意義,就說該對象依賴于另外那個對象。例如:子類幾乎總是依賴于它的父類對象互連6/7/202357第五十七頁,共八十頁,編輯于2023年,星期二耦合(coupling)和內(nèi)聚(cohesion)的思想提供了一個框架,用于評價對象和類的應用是否有效。耦合描述類之間的關系,內(nèi)聚描述類內(nèi)部的關系。耦合和內(nèi)聚6/7/202358第五十八頁,共八十頁,編輯于2023年,星期二從最差的耦合到較好的耦合:內(nèi)部數(shù)據(jù)耦合全局數(shù)據(jù)耦合控制(或順序)耦合組件耦合參數(shù)耦合子類耦合耦合的種類6/7/202359第五十九頁,共八十頁,編輯于2023年,星期二內(nèi)部數(shù)據(jù)耦合發(fā)生在當一個類的實例直接修改另外一個類中的本地數(shù)據(jù)值(實例變量)時。ClassSneakyModifier{ public:voidsneaky(){ //changemyfriendsname myFriend->name=“Lucy”; } Person*myFriend;};ClassPerson{ public:Person(){ name=“Larry”; } stringname;};內(nèi)部數(shù)據(jù)耦合6/7/202360第六十頁,共八十頁,編輯于2023年,星期二全局數(shù)據(jù)耦合發(fā)生在兩個或者更多個類型都依賴于公用的全局數(shù)據(jù)結(jié)構(gòu)而綁定到一起的時候。DoubletodaysDow;ClassOne{ public:voidsetDow(){ todayDow=9473; }}ClassTwo{ public:voidprintDow(){ cout<<“TodaytheDowhit”<<todaysDow; }};全局數(shù)據(jù)耦合6/7/202361第六十一頁,共八十頁,編輯于2023年,星期二一個類必須以一種由任何位置控制的特定的順序來執(zhí)行操作。classMyClass{public: doFirst(){...} doSecond(){...} doThird(){...}}控制或者順序耦合6/7/202362第六十二頁,共八十頁,編輯于2023年,星期二被順序化的類應確保自身能夠以正確的順序?qū)崿F(xiàn)操作,不應僅依賴于調(diào)用者的正確處理classMyClass{public: doStuff(){ doFirst(); doSecond(); doThird(); }protected: doFirst(){...} doSecond(){...} doThird(){...}}控制或者順序耦合6/7/202363第六十三頁,共八十頁,編輯于2023年,星期二組件耦合發(fā)生在一個類包含的數(shù)據(jù)字段或數(shù)值為另外一個類的實例時ClassSet{ . . private: Listdata;};組件耦合6/7/202364第六十四頁,共八十頁,編輯于2023年,星期二參數(shù)耦合發(fā)生在一個類必須調(diào)用另外一個類的服務和例程時,此時兩個類之間所發(fā)生的唯一關系就是一個類需要為另一個類提供參數(shù)數(shù)目、類型和返回值類型。ClassmyClass{ public: voiddoSomething(Setaset){ //dosomethingusingtheargumentvalue . }}參數(shù)耦合6/7/202365第六十五頁,共八十頁,編輯于2023年,星期二子類耦合是面向?qū)ο缶幊趟赜械模枋隽艘粋€類與其父類之間的關系。通過繼承,子類的實例可以被看成父類的實例。ClassParent{ . .}ClassChildextendsParent{ . .}子類耦合6/7/202366第六十六頁,共八十頁,編輯于2023年,星期二類的內(nèi)部內(nèi)聚性是該結(jié)構(gòu)中各個元素之間綁定程度的量度。內(nèi)聚6/7/202367第六十七頁,共八十頁,編輯于2023年,星期二從最弱的內(nèi)聚到最強的內(nèi)聚:隨機內(nèi)聚:對程序隨意劃分邏輯內(nèi)聚:算術(shù)函數(shù)庫時間內(nèi)聚:如實現(xiàn)程序初始化的類通信內(nèi)聚:數(shù)據(jù)或者設備的manager順序內(nèi)聚:避免順序耦合功能內(nèi)聚:類中元素通過執(zhí)行特定功能關聯(lián)起來數(shù)據(jù)內(nèi)聚:數(shù)據(jù)結(jié)構(gòu)內(nèi)聚的種類6/7/202368第六十八頁,共八十頁,編輯于20

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論