程序設計教程:用C++語言編程 第4版 課件 8-2 聚合與組合_第1頁
程序設計教程:用C++語言編程 第4版 課件 8-2 聚合與組合_第2頁
程序設計教程:用C++語言編程 第4版 課件 8-2 聚合與組合_第3頁
程序設計教程:用C++語言編程 第4版 課件 8-2 聚合與組合_第4頁
程序設計教程:用C++語言編程 第4版 課件 8-2 聚合與組合_第5頁
已閱讀5頁,還剩13頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

聚合/組合繼承不是類代碼復用的唯一方式在面向對象程序設計中,有些代碼復用不宜用繼承來實現:繼承除了支持代碼復用外,還體現了類之間在概念上的一般與特殊關系(is-a-kind-of)。如果兩個類之間沒有這個關系,純粹是為了代碼復用而用繼承把它們關聯起來,這樣會造成概念上的混亂。例如:“飛機”類復用“發(fā)動機”類的功能就不宜用繼承來實現。類之間的整體與部分關系類之間除了繼承關系外,還存在一種整體與部分的關系(is-a-part-of),即一個類的對象包含了另一個類的對象。例如,“飛機”類與“發(fā)動機”類之間就是整體與部分的關系。在整體與部分的關系中,新的類(整體類)通過成員類復用已有類的功能。類之間的整體與部分的關系可以是聚合(aggregation)關系組合(composition)關系聚合在聚合關系中,被包含的對象與包含它的對象獨立創(chuàng)建和消亡,被包含的對象可以脫離包含它的對象獨立存在。例如,一個公司與它的員工之間是聚合關系。實現上,聚合類的成員對象一般是采用對象指針表示,用于指向被包含的成員對象,而被包含的成員對象是在外部創(chuàng)建,然后加入到聚合類對象中來的。classA{......};classB//B與A是聚合關系{A*pm;//指向成員對象public:B(A*p){pm=p;}//成員對象在聚合類對象外部創(chuàng)建,然后傳入

~B(){pm=NULL;}//傳進來的成員對象不再是聚合類對象的成員

......};......A*pa=newA;//創(chuàng)建一個A類對象B*pb=newB(pa);//創(chuàng)建一個聚合類對象,其成員對象是pa指向的對象......deletepb;//聚合類對象消亡了,其成員對象并沒有消亡......//pa指向的對象還可以用在其它地方deletepa;//聚合類對象原來的成員對象消亡例:公司由一批員工組成classEmployee//職員類{stringname;

intsalary;public:Employee(constchar*s,intn=0):name(s)

{ salary=n;}voidset_salary(intn){salary=n;}intget_salary()const{returnsalary;}......};constintMAX_NUM_OF_EMPS=1000;classCompany//公司類{Stringname;Employee*group[MAX_NUM_OF_EMPS];//職員數組

intnum_of_emps;//職員人數

public:Company(constchar*s):name(s){num_of_emps=0;}

~Company(){num_of_emps=0;}booladd_employee(Employee*e);boolremove_employee(Employee*e);intget_num_of_emps(){returnnum_of_emps;}......};//創(chuàng)建兩個公司類對象Companyc1("Company_1"),c2("Company_2");//創(chuàng)建兩個職員對象Employeee1("Jack",1000),e2("Jane",2000);//職員Jack加入公司Company_1c1.add_employee(&e1);//職員Jane加入公司Company_1c1.add_employee(&e2);//職員Jack從公司Company_1離職c1.remove_employee(&e1);//職員Jack加入公司Company_2c2.add_employee(&e1);......組合在組合關系中,被包含的對象隨包含它的對象創(chuàng)建和消亡,被包含的對象不能脫離包含它的對象獨立存在。例如,一個人與他的頭、手和腳之間則是組合關系。實現上,組合類的成員對象一般直接是對象,有時也可以采用對象指針表示,但不管是什么表示形式,成員對象一定是在組合類對象內部創(chuàng)建并隨著組合類對象消亡。classA{......};classC//C與A是組合關系{Aa;public:......};......C*pc=newC;//創(chuàng)建一個組合類對象,其成員對象在組合類對象內部創(chuàng)建.....deletepc;//組合類對象與其成員對象都消亡了classA{......};classC//C與A是組合關系{A*pm;//指向成員對象public:C(){pm=newA;}//成員對象隨組合類對象在內部創(chuàng)建

~C(){deletepm;}//成員對象隨組合類對象消亡

......};......C*pc=newC;//創(chuàng)建一個組合類對象,其成員對象在組合類對象內部創(chuàng)建.....deletepc;//組合類對象與其成員對象都消亡了用指針表示成員對象時,既可以實現組合關系,也可以實現聚合關系,它們的區(qū)別在于:在組合關系中,成員對象是由包含它的對象創(chuàng)建和撤銷。在聚合關系中,成員對象不由包含它的對象創(chuàng)建和撤銷。成員對象的創(chuàng)建和撤銷的一般原則:誰創(chuàng)建誰撤銷!線性表由若干元素構成,元素之間有線性的次序關系。classLinearList{ ...... public: boolinsert(intx,intpos); boolremove(int&x,intpos); intelement(intpos)const;

intsearch(intx)const;

intlength()const;};例:利用一個線性表類實現一個隊列類。除了兩個元素外,每個元素都有且僅有一個直接前驅元素和一個直接后繼元素;在除外的兩個元素中,一個只有一個直接前驅元素,另一個只有一個直接后繼元素??梢栽谌我馕恢貌迦搿h除元素。隊列(Queue)是一種特殊的線性表,插入操作在一端,刪除操作在另一端。又稱先進先出表(FirstInFirstOut,FIFO)Queue的實現1(組合):classQueue{ LinearListlist; public:

boolen_queue(inti)

{returnlist.insert(i,list.length());

} boolde_queue(int&i)

{returnlist.remove(i,1); }};Queue的實現2(繼承):classQueue:private

LinearList

{ public: boolen_queue(intx) {returninsert(x,length()); } boolde_queue(int&x) {returnremove(x,1); }};這里為什么不用public繼承?實際上,private繼承已經退化成組合了!繼承與聚合/組合的比較繼承與封裝存在矛盾,聚合/組合與封裝則不存在這個矛盾。在基于繼承的代碼復用中,一個類向外界提供兩種接口:public:對象(實例)用戶public+protected:派生類用戶在基于聚合/組合的代碼復用中,一個類對外只需一個接口:public。繼承的代碼復用功能常??梢杂媒M合來實現。classA{ ...... public: voidf(); voidg();};//組合classB{

...... Aa;public:

voidf(){a.f();}

voidg(){a.g();}

voidh(); ......

溫馨提示

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

最新文檔

評論

0/150

提交評論