版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
繼承--派生類基本內(nèi)容主要內(nèi)容軟件復(fù)用與繼承概述單繼承protected訪問控制繼承方式與子類型派生類對象的初始化與消亡處理派生類對象的賦值軟件復(fù)用在開發(fā)一個新軟件時,把現(xiàn)有軟件或軟件的一部分拿過來用稱為軟件復(fù)用。軟件復(fù)用的一般途徑:函數(shù)(庫)函數(shù)粒度太小,它們往往只能實現(xiàn)一個很小的功能。除了一些最基本的函數(shù)(如數(shù)學(xué)函數(shù)),已有軟件的函數(shù)不是為新軟件設(shè)計的,常常不完全符合新軟件的功能要求。類(庫)類往往實現(xiàn)一個較大的功能。對某個應(yīng)用領(lǐng)域來講,類往往具有通用性。繼承(Inheritance)目前,不加修改地直接復(fù)用已有軟件比較困難。已有軟件的功能與新軟件所需要的功能總是有差別的。解決這個差別的途徑:修改已有軟件的源代碼,它的缺點是:需讀懂源代碼,可靠性差,易出錯源代碼有時難以獲得采用類的繼承機制:定義一個新的類,先把已有的一個或多個類的功能全部包含進來,然后再在新的類中給出新功能的定義或?qū)σ延蓄惖哪承┕δ苓M行重新定義。不需要已有軟件的源代碼,屬于目標(biāo)代碼復(fù)用!基類與派生類在繼承關(guān)系中存在兩個類:基類(或稱父類)和派生類(或稱子類)。派生類擁有基類的所有成員,并可以定義新的成員和對基類的一些成員函數(shù)進行重定義。繼承分為:單繼承和多繼承單繼承:一個類只有一個直接基類。多繼承:一個類有多個直接基類?;惻缮惻缮惢恘基類1…單繼承多繼承繼承對程序設(shè)計的支持繼承機制除了支持軟件復(fù)用外,它還具有下面的作用:
對處理的對象按層次進行分類。有利于問題的描述和解決。對概念進行組合給新類的設(shè)計進一步帶來便利。
研究生教師在職研究生支持軟件的增量開發(fā)。(版本升級)這給軟件開發(fā)和維護帶來便利。A_v1A_v2A_v3單繼承在定義單繼承時,派生類只能有一個直接基類,其定義格式如下:class<派生類名>:[<繼承方式>]<基類名>{ <成員說明表>};
<派生類名>為派生類的名字。<基類名>為直接基類的名字。<成員說明表>是在派生類中新定義的和對基類成員重定義的成員。<繼承方式>用于指出從基類繼承來的成員在派生類中對外的訪問控制
classA//基類{ intx,y; public: voidf(); voidg();};classB:publicA//派生類{ intz;//新成員 public: voidh();//新成員};派生類除了擁有新定義的成員外,還擁有基類的所有成員(基類的構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值操作符重載函數(shù)除外)。例如:Bb; b b.x: b.y: b.z:b.f();//A類中的fb.g();//A類中的gb.h();//B類中的h實際上,派生類的對象包含了基類的一個子對象,該子對象的內(nèi)存空間位于派生類對象內(nèi)存空間的前部。
classA//基類{ intx,y; public: voidf(); voidg();};classB:publicA//派生類{ intz;//新成員 public: voidh();//新成員};定義派生類時一定要見到基類的定義。classA;//聲明classB:publicA//Error{intz;public:voidh(){g();}//Error,編譯程序不知道基類中
//是否有函數(shù)g以及函數(shù)g的原型。};......Bb;//Error,編譯無法確定b所需內(nèi)存空間的大小。友元:如果在派生類中沒有顯式說明,則基類的友元不是派生類的友元;如果基類是另一個類的友元,而該類沒有顯式說明,則派生類也不是該類的友元。C++中,派生類不能直接訪問基類的私有成員。classA{ intx,y; public: voidf(); voidg(){...x,y...}};classB:publicA{ intz; public: voidh() { ...x,y...//Error,x、y為基類的私有成員。
f();//OK
g();//OK,通過函數(shù)g訪問基類的私有成員x和y。
}};
在派生類中訪問基類成員繼承與封裝的矛盾
在派生類中定義新的成員函數(shù)或?qū)愐延谐蓡T函數(shù)重定義時,往往需要直接訪問基類的一些private成員(特別是private數(shù)據(jù)成員),否則新的功能無法實現(xiàn)!而類的private成員是不允許外界使用的(數(shù)據(jù)封裝)!這樣就帶來了繼承與封裝的矛盾。實際上,有了繼承機制以后,一個類的成員有兩種被外界使用的場合:通過類的對象(實例)使用在派生類中使用classA{......
m};classB:publicA{......f(){...m...}//通過派生類使用A的成員m};voidg(){Aa;...a.m...//通過A的對象(實例)使用A的成員m}protected訪問控制在C++中,除了public和private,還提供了另外一種類成員訪問控制:protected用protected說明的成員不能通過對象使用,但可以在派生類中使用。protected訪問控制緩解了封裝與繼承的矛盾C++類向外界提供兩種接口:public:通過對象(類的實例用戶)使用public+protected:供派生類使用classA{ protected: intx,y; public: voidf();};classB:publicA{ ...... voidh() { f();//OK ...x...//OK ...y...//OK }};voidg(){ Aa; a.f();//OK ...a.x...//Error ...a.y...//Error}引進protected成員訪問控制后,基類的設(shè)計者必須要慎重地考慮應(yīng)該把那些成員聲明為protected。一般情況下,應(yīng)該把今后不太可能發(fā)生變動的、有可能被派生類使用的、不宜對實例用戶公開的成員聲明為protected!派生類成員標(biāo)識符的作用域派生類對基類成員的訪問除了受到基類的訪問控制的限制以外,還要受到標(biāo)識符作用域的限制。對基類而言,派生類成員標(biāo)識符的作用域是嵌套在基類作用域中的。classB:publicA{......public:voidg(){f();}//OK}classA{......public:voidf(){g();}//Error!......}如果派生類中定義了與基類同名的成員,則基類的成員名在派生類的作用域內(nèi)不直接可見(被隱藏,Hidden),訪問基類同名的成員時要用基類名受限。例如:classB:publicA{ intz;public: voidf();//不是重載A的f! voidh() { f();//B類中的f
A::f();//A類中的f }};注意:B類中的f與A類中的f不屬于函數(shù)名重載,因為它們屬于不同的作用域。classA//基類{ intx,y; public: voidf(); voidg();};即使派生類中定義了與基類同名但參數(shù)不同的成員函數(shù),基類的同名函數(shù)在派生類的作用域中也是不直接可見的,仍然需要用基類名受限方式來使用之:classB:publicA{ intz; public: voidf(int); voidh() { f(1);//OK f();//Error A::f();//OK }};classA//基類{ intx,y; public: voidf(); voidg();};也可以在派生類中使用using聲明把基類中某個的函數(shù)名對派生類開放:classB:publicA{ intz; public:
usingA::f; voidf(int); voidh() { f(1);//OK f();//OK,等價于A::f(); }};classA//基類{ intx,y; public: voidf(); voidg();};基類成員在派生類中對外的訪問控制在C++中,派生類擁有基類的所有成員。問題是:基類的成員在派生類中對外的訪問控制是什么?即,派生類的用戶能訪問基類的哪些成員?classA{ public: voidf(); protected: voidg(); private: voidh();};classB:...A{......};//B的用戶2classC:publicB{ public: voidr() { f();//? g();//? h();//?
}};//B的用戶1voidfunc(){Bb;b.f();//?b.g();//?b.h();//?}繼承方式上面的問題由基類的訪問控制與派生類的繼承方式共同決定。繼承方式在定義派生類時指定:class<派生類名>:[<繼承方式>]<基類名>{ <成員說明表>};繼承方式可以是:public、private和protected。默認(rèn)的繼承方式為:private。繼承方式的含義
基類成員派生類繼承方式publicprivateprotectedpublicpublic不可直接訪問protectedprivateprivate不可直接訪問privateprotectedprotected不可直接訪問protectedclassA{ public: voidf(); protected: voidg(); private: voidh();};classB:protectedA{ //f為protected
//g為protected
//h為不可直接訪問public: voidq() {f();//?
g();//?
h();//?
}};classC:publicB{ public: voidr() { f();//OK g();//OK h();//Error
q();//?
}};voidfunc(){Bb;b.f();//Errorb.g();//Errorb.h();//Errorb.q();//?}?跟B的繼承方式無關(guān)!繼承方式的調(diào)整classA{public: voidf1(); voidf2(); voidf3();protected: voidg1(); voidg2(); voidg3();};classB:privateA{public: A::f1;//把f1調(diào)整為public A::g1;//把g1調(diào)整為public
//是否允許弱化基類的訪問控制要視具體的實現(xiàn)而定protected: A::f2;//把f2調(diào)整為protected A::g2;//把g2調(diào)整為protected
......};public繼承與子類型public繼承有特殊的作用,它可以實現(xiàn)類之間的子類型關(guān)系:對用類型T表達的所有程序P,當(dāng)用類型S去替換程序P中的所有的類型T時,程序P的功能不變,則稱類型S是類型T的子類型。在C++中,把類看作類型,把以public方式繼承的派生類看作是基類的子類型:對基類對象能實施的操作也能作用于派生類對象。在需要基類對象的地方可以用派生類對象去替代
。例如,對于下面的兩個類A和BclassA//基類{ intx,y; public:
voidf(){x++;y++;}
......};classB:publicA//派生類{
intz; public:
voidg(){z++;}
......};下面的操作是合法的:
Aa;Bb;b.f();//OK,基類的操作可以實施到派生類對象a=b;//OK,派生類對象可以賦值給基類對象,
//屬于派生類但不屬于基類的數(shù)據(jù)成員將被忽略A*p=&b;//OK,基類的指針可以指向派生類對象A&a2=b;//OK,基類的引用可以引用派生類對象......voidfunc1(A*p);voidfunc2(A&x);voidfunc3(Ax);func1(&b);func2(b);func3(b);//OK下面的操作是不合法的:Aa;Bb;a.g();//Error,基類對象a沒有g(shù)這個成員函數(shù)。b=a;//Error,它將導(dǎo)致b有不一致的成員數(shù)據(jù)
//(a中沒有這些數(shù)據(jù))。B*q=&a;//Error,“q->g();”將修改不屬于a的數(shù)據(jù)!B&b2=a;//Error,“b2.g();”將修改不屬于a的數(shù)據(jù)!......voidfunc1(B*p);voidfunc2(B&x);voidfunc3(Bx);func1(&a);func2(a);func3(a);//Error派生類對象的初始化和消亡處理派生類對象的初始化由基類和派生類共同完成:從基類繼承的數(shù)據(jù)成員由基類的構(gòu)造函數(shù)初始化;派生類新的數(shù)據(jù)成員由派生類的構(gòu)造函數(shù)初始化。當(dāng)創(chuàng)建派生類的對象時,先執(zhí)行基類的構(gòu)造函數(shù),再執(zhí)行派生類構(gòu)造函數(shù)。默認(rèn)情況下,調(diào)用基類的默認(rèn)構(gòu)造函數(shù),如果要調(diào)用基類的非默認(rèn)構(gòu)造函數(shù),則必須在派生類構(gòu)造函數(shù)的成員初始化表中顯式指出。當(dāng)派生類對象消亡時,先調(diào)用本身類的析構(gòu)函數(shù),執(zhí)行完后會去自動調(diào)用基類的析構(gòu)函數(shù)。classA{ intx; public: A(){x=0;} A(inti){x=i;}};classB:publicA{ inty; public: B(){y=0;} B(inti){y=i;} B(inti,intj):A(i){y=j;}};......Bb1;//執(zhí)行A::A()和B::B(),b1.x等于0,b1.y等于0。Bb2(1);//執(zhí)行A::A()和B::B(int),b2.x等于0,b2.y等于1。Bb3(1,2);//執(zhí)行A::A(int)和B::B(int,int),b3.x等于1,
//b3.y等于2。對一個未提供任何構(gòu)造函數(shù)的類,如果它有基類,編譯程序有時會隱式地為之提供一個默認(rèn)構(gòu)造函數(shù),其作用是負責(zé)調(diào)用基類的默認(rèn)構(gòu)造函數(shù)。對一個未提供析構(gòu)函數(shù)的類,如果它有基類,編譯程序有時也會隱式地為之提供一個析構(gòu)函數(shù),其作用是負責(zé)調(diào)用基類的析構(gòu)函數(shù)。如果一個類D既有基類B、又有成員對象類M,則在創(chuàng)建D類對象時,構(gòu)造函數(shù)的執(zhí)行次序為:B->M->D當(dāng)D類的對象消亡時,析構(gòu)函數(shù)的執(zhí)行次序為:D->M->B派生類的隱式拷貝構(gòu)造函數(shù)(由編譯程序提供):對派生類中新定義的成員進行拷貝初始化外。調(diào)用基類的拷貝構(gòu)造函數(shù)實現(xiàn)對基類成員的初始化。派生類自定義的拷貝構(gòu)造函數(shù):在默認(rèn)情況下調(diào)用基類的默認(rèn)構(gòu)造函數(shù)對基類成員初始化。需要在“成員初始化表”中顯式地指出調(diào)用基類的拷貝構(gòu)造函數(shù)來實現(xiàn)對基類成員的初始化。派生類拷貝構(gòu)造函數(shù)classA{
intx;
......};classB:publicA{ inty;
public:B(){......}
B(constB&b)//調(diào)用A類的默認(rèn)構(gòu)造函數(shù) { y=b.y;//對派生類新定義的成員進行初始化 }
......};Bb1;Bb2(b1);:A(b)
//調(diào)用A類的拷貝構(gòu)造函數(shù)派生類對象的賦值操作派生類隱式的賦值操作:對派生類成員進行賦值。調(diào)用基類的賦值操作對基類成員進行賦值。派生類自定義的賦值操作:不會自動調(diào)用基類的賦值操作。需要在自定義的賦值操作符重載函數(shù)中顯式地指出調(diào)用基類的賦值操作。classA{intx;
......};classB:publicA{ inty; public: B&operator=(constB&b) { if(&b==this)return*this;//防止自身賦值。
*(A*)this=b;//調(diào)用基類的賦值操作符對基類成員
//進行賦值。也可寫成:this->A::operator=(b); y=b.y;//對派生類新定義的成員賦值 return*this; }
......};......Bb1,b2;b1=b2;繼承的實例:一個公司中的職員類
和部門經(jīng)理類的設(shè)計。
classEmployee//普通職員類{ Stringname;//String為字符串類。
intsalary; publ
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024產(chǎn)品銷售區(qū)域代理合同模板
- 2024租車合同協(xié)議書公司單位租車協(xié)議書
- 2024版獨家代理合同樣本
- 2024年廣場文化建設(shè)施工合同
- 2024年度貨物采購與供應(yīng)協(xié)議
- 陀螺課件圖片教學(xué)課件
- 2024年度勞動合同標(biāo)的:高級管理人員雇傭
- 2024解除土地流轉(zhuǎn)合同
- 2024年度環(huán)保項目技術(shù)研發(fā)與許可使用合同
- 2024年度房屋買賣合同(高檔住宅)
- 人教版四年級上冊三位數(shù)乘兩位數(shù)豎式練習(xí)400題及答案
- 大學(xué)生國防教育
- 智慧校園匯報材料課件
- 2024年遼寧盤錦國發(fā)實業(yè)有限公司招聘筆試參考題庫附帶答案詳解
- 樓蘭古國完整
- 青茶專業(yè)知識
- 加大技術(shù)研發(fā)投入推動技術(shù)創(chuàng)新
- 醫(yī)院管理學(xué)教學(xué)完整版
- 老人艾滋病防控知識講座
- 基因突變的發(fā)生和表達的實驗探究
- 化工原理實驗課后思考題及化工原理實驗思考題
評論
0/150
提交評論