




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
第11章繼承與派生主要內(nèi)容11.1類的繼承與派生11.2派的繼承方式11.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)11.4多重繼承11.5應用實例11.1類的繼承與派生類的繼承:新類從已有類(父類)那里獲得其已有特性。類的派生:已有類(父類)產(chǎn)生新的子類。派生類繼承了基類的所有數(shù)據(jù)成員和成員函數(shù),并可對成員作必要的增加或調(diào)整。基類和派生類相對而言:一個基類可派生出多個派生類,每個派生類又可作為基類再派生出新的派生類。11.1.1繼承與派生的實例設計的原則:公共的特性抽象封裝成基類,獨有的特性在派生類里實現(xiàn)。11.1.1繼承與派生的實例學校人員管理:學生教師管理人員教師管理人員人員(姓名,性別,年齡,學院)(學號,姓名,性別,年齡,學院,專業(yè),班級)(工號,姓名,性別,年齡,學院,職稱)(工號,姓名,性別,年齡,學院,科室,職務)(工號,姓名,性別,年齡,學院,職稱,科室,職務)人類教師類學生類管理人員類教師管理人員類多繼承:派生類有多個基類單繼承:派生類只有一個基類直接基類間接基類11.1.1繼承與派生的實例單繼承(singleinheritance):一個派生類只從一個基類派生。多重繼承(multipleinheritance):一個派生類有兩個或兩個以上基類。11.1.2派生類的定義聲明派生類的一般形式class派生類名:[繼承方式]基類名{派生類新增的成員};繼承方式:public,private和protected。默認繼承方式:private?;悾喝藛T類classPerson //定義Person類{ public:
Person(constchar*Name,intAge,charSex);
char*GetName(); intGetAge();
charGetSex();voidDisplay();private: charname[50]; charsex; intage;};classStudent:publicPerson//公有繼承{public:
Student(char*pName,intAge,charSex,char*pId,floatscore):Person(pName,Age,Sex);
//派生類新增的成員函數(shù) char*GetId();
floatGetScore();
voidDisplay(); private:
//派生類新增的數(shù)據(jù)成員charsid[9]; floatscore;};派生類:學生類派生類:教師類classTeacher:publicPerson{//公有繼承public:
Teacher(char*pName,intAge,charSex,char*pId,char*pprof,floatSalary):Person(pName,Age,Sex);
char*GetId();
char*GetProf();
floatGetSalary();
voidDisplay();private: charid[9];charprof[12]; floatsalary;};11.1.3派生類的生成過程(1)繼承基類成員(2)改造基類成員(3)增加新的成員11.2類的繼承方式公用繼承私有繼承保護繼承繼承方式影響基類成員在派生類的訪問屬性(1)公用繼承(publicinheritance)基類的公用和保護成員在派生類中保持原有訪問屬性,私有成員仍為基類私有。(2)私有繼承(privateinheritance)基類的公用和保護成員在派生類中成了私有成員,私有成員仍為基類私有。(3)受保護的繼承(protectedinheritance)基類的公用和保護成員在派生類中成了保護成員,私有成員仍為基類私有。11.2.1公用繼承公有繼承時,基類的公有成員和保護成員作為派生類的成員時,都保持原有狀態(tài),而私有成員仍是私有。公有繼承時,派生類的對象只可訪問基類中的公有成員,不能訪問其它成員。派生類的成員函數(shù)可以訪問基類中的公有成員和保護成員,不可訪問其私有成員。11.2.1公用繼承classstudent{private:intage;protected:charsex;public:intGetage(){returnage;}};classgraduatestudent:publicstudent{private:intstunum;
public:voiddisplay();};即:student::Getage()//
//不可訪問基類的私有成員//派生類的私有成員//基類的公有成員公有繼承voidgraduatestudent::display()//派生類成員函數(shù)定義{cout<<"age:"<<age<<endl;cout<<"stunum:"<<stunum<<endl;cout<<"age:"<<Getage()<<endl;cout<<"sex:"<<sex<<endl;//即:student::sex基類的保護成員}voidmain(){graduatestudentzh;//生成派生類對象
cout<<zh.Getage();//即:student::Getage();基類中的公有成員
zh.display();//訪問派生類中的公有成員
cout<<zh.sex;cout<<zh.stunum;cout<<zh.age;}//
//
error,訪問基類中保護成員//
//
error,訪問派生類中私有成員//
//
error,訪問基類中私有成員公有繼承11.2.2私有繼承私有繼承時,基類的公有成員和保護成員都作為派生類的私有成員,并且不能被這個派生類的子類所訪問。私有繼承時,基類的成員只能由直接派生類訪問,而無法再往下繼承。私有繼承classstudent{private:intage;protected:charsex;public:intGetage(){returnage;}};classgraduatestudent:privatestudent{private:intstunum;public:voiddisplay();};私有繼承voidgraduatestudent::display()//派生類成員函數(shù)定義{
//cout<<"age:"<<age<<endl;//不可訪問基類的私有成員
cout<<"stunum:"<<stunum<<endl;//派生類的私有成員
cout<<"age:"<<Getage()<<endl;//基類的公有成員
cout<<"sex:"<<sex<<endl;
//即:student::sex基類的保護成員
}私有繼承voidmain(){graduatestudentzh;//生成派生類對象
//zh.Getage();//error,不能訪問私有成員zh.display();//訪問派生類中的公有成員//cout<<zh.sex;//error,不能訪問私有成員
//cout<<zh.stunum;//error,不能訪問私有成員
//cout<<zh.age;//error,不能訪問私有成員}11.2.3保護繼承保護繼承時,基類的所有公有成員和保護成員都作為派生類的保護成員,并且只能被它的派生類成員函數(shù)或友元訪問,基類的私有成員仍是私有的。保護繼承時,派生類的成員函數(shù)可以直接訪問從基類繼承而來的成員,但在類外不能直接訪問。保護繼承classstudent{private:intage;protected:charsex;public:intGetage(){returnage;}};classgraduatestudent:protectedstudent{private:intstunum;public:voiddisplay();};保護繼承voidgraduatestudent::display()//派生類成員函數(shù)定義{//cout<<"age:"<<age<<endl;//不可訪問基類的私有成員cout<<"stunum:"<<stunum<<endl;//派生類的私有成員cout<<"age:"<<Getage()<<endl;//基類的公有成員cout<<"sex:"<<sex<<endl;//即:student::sex
基類的保護成員
}保護繼承voidmain(){graduatestudentzh;//生成派生類對象
//zh.Getage();//error,不能訪問保護成員zh.Getnum();//訪問派生類中的公有成員//cout<<zh.sex;//
error,不能訪問保護成員
//cout<<zh.stunum;//error,不能訪問私有成員
//cout<<zh.age;//
error,不能訪問保護成員}11.2類的繼承方式派生類成員派生類中派生類外部下層派生類公用成員可以可以可以保護成員可以不可以可以私有成員可以不可以不可以不可訪問成員不可以不可以不可以多級派生時的訪問屬性直接派生類、間接派生類直接基類、間接基類例多級派生的訪問屬性classA
//基類{public:inti;
protected:voidf2();intj;private:intk;};classB:public
A{public:voidf3();
protected:voidf4();
private:intm;};classC:protectedB{public:voidf5();private:intn;};例多級派生的訪問屬性各成員在不同類中的訪問屬性if2jkf3f4mf5n基類A公有保護保護私有公有派生類B公有保護保護不可訪問公有保護私有保護派生類C保護保護保護不可訪問保護保護不可訪問公有私有多級派生時的訪問屬性派生類都不能訪問基類的私有成員,私有成員只能被本類的成員函數(shù)訪問。都采用公有繼承的多級派生,則直到最后一級派生類都能訪問基類的公有和保護成員。都采用私有繼承方式,經(jīng)過若干次派生之后,基類的所有成員變成不可訪問。都采用保護繼承方式,在派生類外無法訪問派生類中的任何成員。公有繼承:最常用。11.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)派生類的析構(gòu)函數(shù)
構(gòu)造函數(shù)不能被繼承,對派生類必須重新定義構(gòu)造函數(shù)。在聲明一個派生類對象時,系統(tǒng)首先要通過派生類的構(gòu)造函數(shù)調(diào)用基類的構(gòu)造函數(shù),對基類成員初始化;然后對派生類中新增的成員初始化。派生類的對象的數(shù)據(jù)結(jié)構(gòu)是由基類中說明的數(shù)據(jù)成員和派生類中說明的數(shù)據(jù)成員共同構(gòu)成。將派生類的對象中由基類中說明的數(shù)據(jù)成員和操作所構(gòu)成的封裝體稱為基類子對象,它由基類中的構(gòu)造函數(shù)進行初始化。11.3.1派生類的構(gòu)造函數(shù)派生類構(gòu)造函數(shù)初始化對象基類的數(shù)據(jù)成員派生類新增的數(shù)據(jù)成員思路:在執(zhí)行派生類的構(gòu)造函數(shù)時,調(diào)用基類的構(gòu)造函數(shù)。形式:派生類構(gòu)造函數(shù)(參數(shù)):參數(shù)化列表{派生類新增成員的初始化語句}36派生類的構(gòu)造函數(shù)帶有子對象的派生類的構(gòu)造函數(shù)形式:派生類構(gòu)造函數(shù)(參數(shù)表):基類構(gòu)造函數(shù)(參數(shù)表),對象成員1的構(gòu)造函數(shù)(參數(shù)表)……,對象成員n的構(gòu)造函數(shù)(參數(shù)表){派生類新增成員的初始化語句}37【例11-4】構(gòu)造函數(shù)的調(diào)用順序舉例#include<iostream>usingnamespacestd;classBase{ inta; public: Base(intx):a(x){//基類的構(gòu)造函數(shù)
cout<<"constructBaseclass"<<a<<endl; }};38classsubBase:publicBase{private:
intb,c;//類subBase中新增的普通成員
constintd;
Basex,y;//類subBase中新增的對象成員public:
subBase(intt):y(t+2),x(t+1),d(t+3),Base(t){
b=t;
c=t;
cout<<"constructsubBaseclass"<<b<<""<<c<<""<<d<<endl; }};intmain(){ subBases1(9); return0;//建立subBase類對象s1}constructBaseclass9constructBaseclass10constructBaseclass11constructsubBaseclass9912派生類構(gòu)造函數(shù)的調(diào)用順序
首先調(diào)用基類的構(gòu)造函數(shù);
其次執(zhí)行參數(shù)化表中部分所列出的對象成員的構(gòu)造函數(shù);
最后執(zhí)行派生類構(gòu)造函數(shù)的函數(shù)體。即先祖先(基類),再客人(對象成員),后自己(派生類本身)。11.3.2派生類的析構(gòu)函數(shù)派生類不能繼承基類的析構(gòu)函數(shù)?;惖那謇砉ぷ魅杂苫愇鰳?gòu)函數(shù)負責。執(zhí)行派生類的析構(gòu)函數(shù)時,系統(tǒng)自動調(diào)用基類和子對象的析構(gòu)函數(shù)。調(diào)用順序:先執(zhí)行派生類的析構(gòu)函數(shù),然后調(diào)用子對象的析構(gòu)函數(shù),最后調(diào)用基類的析構(gòu)函數(shù)。42【例11-5】析構(gòu)函數(shù)的調(diào)用順序舉例。#include<iostream>usingnamespacestd;classBase{ inta; public: Base(intx):a(x){ //基類的構(gòu)造函數(shù)
cout<<"constructBaseclass:"<<a<<endl; } ~Base(){ //基類Base的析構(gòu)函數(shù)
cout<<"destructBase:"<<a<<endl; }};classsubBase:publicBase{private:
intb,c;
constintd;
Basex,y;public: subBase(intt):y(t+2),x(t+1),d(t+3),Base(t){
b=t;
c=t;
cout<<"constructsubBaseclass:"<<b<<""<<c<<""<<d<<endl; } ~subBase(){
cout<<"destructsubBase:"<<b<<""<<c<<""<<d<<endl; }};intmain(){ subBases1(9); return0;}constructBaseclass:9constructBaseclass:10constructBaseclass:11constructsubBaseclass:9912destructsubBase:9912destructBase:11destructBase:10destructBase:911.4多重繼承多重繼承概念多重繼承的二義性虛基類4611.4.1多重繼承概念多重繼承:允許一個派生類同時繼承多個基類。聲明多重繼承的方法class派生類名:繼承方式基類名1,繼承方式基類名2,...,繼承方式基類名n{定義派生類自己的成員};47多繼承的構(gòu)造函數(shù)一般格式為:<派生類名>(<總參數(shù)表>):
<基類名1>(<參數(shù)表1>),<基類名2>(<參數(shù)表2>),…<子對象名>(<參數(shù)表n+1>){<派生類構(gòu)造函數(shù)體>};它必須同時負責該派生類所有基類構(gòu)造函數(shù)的調(diào)用。同時,派生類的參數(shù)個數(shù)必須包含完成所有基類初始化所需的參數(shù)個數(shù)。派生類構(gòu)造函數(shù)的調(diào)用順序是:先執(zhí)行所有基類的構(gòu)造函數(shù)再執(zhí)行子對象類的構(gòu)造函數(shù)(若有)再執(zhí)行派生類本身的構(gòu)造函數(shù)注意:同一層次的各基類構(gòu)造函數(shù)的執(zhí)行順序取決于定義派生類時所指定的各基類順序,與派生類構(gòu)造函數(shù)中所定義的成員初始化表的各項順序無關?!纠?1-6】多重繼承舉例。#include<iostream>usingnamespacestd;classCBase1{ protected: intb; public: CBase1(intx=0){
b=x; cout<<"ConstructCBase1!"<<b<<endl; } ~CBase1(){
cout<<"DestructCBase1!"<<b<<endl; }};classCBase2{protected:
intb;public:
CBase2(intx=0){
b=x;
cout<<"ConstructCBase2!"<<b<<endl;
}
~CBase2(){
cout<<"DestructCBase2!"<<b<<endl;
}};classCDerived:publicCBase1,privateCBase2{protected:
CBase1b1;
CBase2b2;
intd;public:
CDerived(intx,inty,intz):b1(y),CBase2(y),b2(z),CBase1(x){
d=z;
cout<<"ConstructCDerived!"<<d<<endl;
}
~CDerived(){
cout<<"DestructCDerived!"<<d<<endl;
}};intmain(){ CDerivedd1(1,2,3); return0;}ConstructCBase1!1ConstructCBase2!2ConstructCBase1!2ConstructCBase2!3ConstructCDerived!3DestructCDerived!3DestructCBase2!3DestructCBase1!2DestructCBase2!2DestructCBase1!111.4.2多重繼承的二義性多重繼承情況下的二義性問題可分為兩種情況(1)從不同基類繼承的同名成員,在引用時產(chǎn)生二義性。(2)當?shù)蛯优缮悘牟煌穆窂缴隙啻卫^承同一個基類時,也會產(chǎn)生二義性。(1)兩個基類有同名成員classA{public:inta;voiddisplay();};classB{public:inta;voiddisplay();};classC:publicA,publicB{public:intb;voidshow();};voidmain(){Cc1;c1.a=3;c1.display();}編譯后:errorC2385:'C::a'isambiguouserrorC2385:'C::display'isambiguous消除二義性有兩種方法1、使用相應的類名來標識 c1.A::display();2、由派生類提供統(tǒng)一的接口 voidC::show() {
A::display();
B::display();
…… }(2)兩個基類和派生類三者都有同名成員。將C類聲明改為:classC:publicA,publicB{public:inta;voiddisplay();};voidmain(){Cc1;c1.a=3;c1.display();}會有問題么?規(guī)則:基類的同名成員在派生類中被屏蔽,成為“不可見”的,或者說,派生類新增加的同名成員覆蓋了基類中的同名成員。因此如果在定義派生類對象的模塊中通過對象名訪問同名的成員,則訪問的是派生類的成員。(3)如果C從類A和B派生,而它們又從同一個基類派生classN{public:inta;voiddisplay()
{cout<<"A::a="<<a<<endl;}};classA:publicN{public:inta1;};classB:publicN{public:inta2;};classC:publicA,publicB{public:inta3;voidshow(){cout<<"a3="<<a3<<endl;}};intmain(){Cc1;//定義C類對象c1……..}怎樣才能訪問類A中從基類N繼承下來的成員呢?inta3;顯然不能用c1.a=3;c1.display();或c1.N::a=3;c1.N::display();因為這樣依然無法區(qū)別是類A中從基類N繼承下來的成員,還是類B中從基類N繼承下來的成員。應當通過類N的直接派生類名來指出要訪問的是類N的哪一個派生類中的基類成員。如:c1.A::a=3;c1.A::display();11.4.3虛基類虛基類的作用:在繼承間接共同基類時只保留一份成員。聲明虛基類的一般形式注:不是在聲明基類時聲明,而是在聲明派生類時,指定繼承方式時聲明。class派生類名:virtual
繼承方式基類名classA//聲明基類A{…};classB:virtualpublicA//聲明A是B的虛基類{…};classC:virtualpublicA//聲明A是C的虛基類{…};注:為保證虛基類在派生類中只繼承一次,應把該基類的所有直接派生類聲明為虛基類。67【例11-9】利用虛基類避免產(chǎn)生二義性。classFurniture{
public: Furniture(){ cout<<"constructFurniture"<<endl; } voidSetPrice(doubled){ price=d; } doubleGetPrice(){ returnprice; } protected: doubleprice;};classBed:virtualpublicFurniture{
public: Bed(){ cout<<"constructBed"<<endl; } voidSleep(){ cout<<"Sleeping..."; }};classSofa:virtualpublicFurniture{
public: Sofa(){ cout<<"constructSofa"<<endl; } voidWatchTV(){ cout<<"WatchingTV.\n"; }};classSleeperSofa:publicBed,publicSofa{ public: SleeperSofa():Sofa(),Bed(){ cout<<"constructSleeperSofa"<<endl; } voidFoldOut(){ cout<<"Foldoutthesofa.\n"; } voidFunction(){ Sleep(); WatchTV(); }};intmain(){ SleeperSofass; ss.SetPrice(2000); cout<<"PriceofSleeperSofa:"<<ss.GetPrice()<<endl; cout<<"FunctionofSleeperSofa:"; ss.Function(); return0;}constructFurnitureconstructBedconstructSofaconstructSleeperSofaPriceofSleeperSofa:2000FunctionofSleeperSofa:Sleep
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國細木工板橫向拼板機行業(yè)發(fā)展研究報告
- 2025至2030年中國純銀懷表市場分析及競爭策略研究報告
- 周之冕花鳥畫藝術風格探究
- 2025至2030年中國粗紡花呢面料行業(yè)投資前景及策略咨詢報告
- 2025至2030年中國竹條燈籠市場調(diào)查研究報告
- 2025至2030年中國空調(diào)用小型塔數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年中國硬質(zhì)合金歐洲型木工鉆嘴市場分析及競爭策略研究報告
- 2025至2030年中國礦用智能超聲物位儀市場分析及競爭策略研究報告
- 2025至2030年中國真絲絨毯行業(yè)投資前景及策略咨詢報告
- 2025至2030年中國直流油泵市場現(xiàn)狀分析及前景預測報告
- 大學生職業(yè)生涯規(guī)劃成品
- 2024年全國半導體行業(yè)職業(yè)技能競賽(半導體分立器件和集成電路裝調(diào)工賽項)理論考試題庫(含答案)
- 鋁合金模板細部節(jié)點深化設計指導圖冊(三維圖)
- 信用卡協(xié)商還款協(xié)議書模板
- GB 20997-2024輕型商用車輛燃料消耗量限值及評價指標
- 福建省福清市2023-2024學年高一下學期期中考試數(shù)學試題(原卷版)
- 2023六年級英語下冊 Fun Time(Recycle)教案 人教精通版(三起)
- 我是記憶小達人(課件)-心理健康六年級
- 應急預案編制計劃再改樣本
- 中醫(yī)治療失眠課件
- 2022年河南工業(yè)和信息化職業(yè)學院單招面試題庫及答案解析
評論
0/150
提交評論