第8章-繼承和派生_第1頁
第8章-繼承和派生_第2頁
第8章-繼承和派生_第3頁
第8章-繼承和派生_第4頁
第8章-繼承和派生_第5頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第8章繼承和派生

在C++中可重用性是通過繼承(inheritance)這一機制來實現(xiàn)的。繼承是C++的一個重要組成部分。8.1繼承和派生的概念

在C++中,所謂“繼承”就是在一個已存在的類的基礎(chǔ)上建立一個新的類。一個新類從已有的類那里獲得其已有特性,這種現(xiàn)象稱為類的繼承。通過繼承,一個新建子類從已有的父類那里獲得父類的特性。從另一角度說,從已有的類(父類)產(chǎn)生一個新的子類,稱為類的派生。類的繼承是用已有的類來建立專用類的編程技術(shù)。8.1.1基類與派生類

1.繼承與派生交通工具飛機滑翔機直升飛機噴氣式飛機交通工具飛機滑翔機直升飛機噴氣式飛機已存在的類(例如“交通工具”)稱為“基類”或“父類”。新建立的類(例如“飛機”)稱為“派生類”或“子類”。一個基類可以派生出多個派生類,每一個派生類又可以作為基類再派生出新的派生類,因此基類和派生類是相對而言的。2.基類與派生類請注意圖中箭頭的方向,在本書中約定,箭頭表示繼承的方向,從派生類指向基類。8.1.2繼承與派生的作用1.避免公用代碼的重復(fù)開發(fā),在減少代碼和數(shù)據(jù)冗余的同時,節(jié)省程序開發(fā)的時間,提高程序開發(fā)的效率和質(zhì)量。2.通過增強代碼一致性來減少模塊間的接口和界面。3.通過層次關(guān)系來組織對象,使得高層類作為低層類的抽象,有利于程序員掌握對象的共性,在此基礎(chǔ)上,就能更快地掌握低層類中的個性特征,給編程與代碼重用帶來方便。8.1.3派生類的聲明聲明一個派生類的一般格式為:class派生類名:派生存取說明符(可?。┗惷鹻 //派生類新增的數(shù)據(jù)成員和成員函數(shù)};

派生類名”是要從基類派生出的新類的名字,“基類名”是一個已經(jīng)定義好的基類的名字,“派生存取說明符”可以是關(guān)鍵字public或protected或private,派生存取說明符的作用會在后面詳細(xì)介紹,“派生存取說明符”可以省略,默認(rèn)為private,即私有派生。//定義一個基類(Student類)classStudent{ public: charname[10];//姓名 intage; //年齡 charsex; //性別 charclassname[20]; //班級名稱};//定義一個派生類(GraduateStudent類)classGraduateStudent:publicStudent{ public: charAdvisorname[10];//導(dǎo)師 intqualifiergrade; //資格考試分};8.2派生類成員的訪問控制

8.2.1派生類成員訪問控制簡介從一個基類派生出一個子類時,可以通過指定派生時的存取說明符來實現(xiàn)對派生類成員的訪問控制。既然派生類中包含基類成員和派生類自己增加的成員,就產(chǎn)生了這兩部分成員的關(guān)系和訪問屬性的問題。在建立派生類的時候,并不是簡單地把基類的私有成員直接作為派生類的私有成員,把基類的公用成員直接作為派生類的公用成員。實際上,對基類成員和派生類自己增加的成員是按不同的原則處理的。8.2.2private、protected與public類成員

1.private類成員一個類中的私有(private)成員(包括數(shù)據(jù)成員和成員函數(shù))只能被它們所在類的成員函數(shù)和友元函數(shù)訪問,在C++中類成員存取說明符缺省的情況下的存取特征都是私有的(private)?!纠?.1】類私有成員的定義和訪問#include<iostream.h>classPerson { //Person類的三個私有成員 charname[10];//姓名 private: intage; //年齡 charsex; //性別}; main() { PersonP1; P1.age=20; //非法 cout<<P1.name<<endl; //非法 return0; }2.public類成員

一個類中的公有(public)成員(包括數(shù)據(jù)成員和成員函數(shù))可以被程序中任何代碼(包括函數(shù))訪問,一般情況下,應(yīng)盡量將類的數(shù)據(jù)成員聲明為私有(private),然后為需要被類外部訪問的數(shù)據(jù)成員提供公有的成員函數(shù),實現(xiàn)對私有成員的設(shè)置和訪問,這種結(jié)構(gòu)能夠向類的客戶很好的隱藏實現(xiàn)方法,在有效減少錯誤的同時,可以增強程序的可修改性。3.protected類成員使用protected聲明的稱為保護成員。任何一個類的保護成員僅可以被其自己和派生類的所有非靜態(tài)成員函數(shù)和友元函數(shù)直接訪問,也就是說其他的外部函數(shù)是不能訪問它的。因此,對于那些既要對外界隱藏,又要能被派生類訪問的成員,可以將它們聲明為保護成員。

如果基類聲明了私有成員,那么任何派生類都是不能訪問它們的,若希望在派生類中能訪問它們,應(yīng)當(dāng)把它們聲明為保護成員。如果在一個類中聲明了保護成員,就意味著該類可能要用作基類,在它的派生類中會訪問這些成員。8.2.3三種派生方式的定義

1.私有(private)派生

在聲明一個派生類時將派生方式指定為private的,稱為私有派生,用私有派生方式建立的派生類稱為私有派生類,其基類稱為私有基類。由私有派生得到的派生類,它從基類繼承的成員都將變?yōu)樗接谐蓡T,也就是說通過私有派生,派生類從基類繼承來的公有成員和保護成員都將變成派生類的私有成員,這些成員將只能被派生類的成員函數(shù)和友元函數(shù)訪問。需要重點說明的是,基類的私有成員經(jīng)過私有派生后繼續(xù)保持其基類的私有成員身份,無法被派生類訪問。

2.保護(protected)派生由保護派生得到的派生類,它從基類繼承的公有和保護成員都將變?yōu)榕缮惖谋Wo成員?;惖乃接谐蓡T經(jīng)過保護派生后繼續(xù)保持其基類的私有成員身份,依然無法被派生類訪問。保護派生的特點是:基類的公用成員和保護成員在派生類中都成了保護成員,其私有成員仍為基類私有。也就是把基類原有的公用成員也保護起來,不讓類外任意訪問。3.公有(public)派生由公有派生得到的派生類,它從基類繼承的成員都將維持原有訪問控制特征,即通過公有派生后,派生類從基類繼承的公有成員在派生類中仍然是公有成員,保護成員仍然是保護成員,而基類的私有成員經(jīng)過公有派生后繼續(xù)保持其基類的私有成員身份,依然無法被派生類訪問。8.2.4派生類成員訪問控制規(guī)則

1.派生類中新增成員的訪問控制遵循類成員訪問控制的規(guī)則。存取說明符訪問控制規(guī)則Private此派生類的非靜態(tài)成員函數(shù)和友元函數(shù)可以直接訪問Protected此派生類和其子類非靜態(tài)成員函數(shù)和友元函數(shù)可以訪問Public任何非靜態(tài)成員函數(shù),友元函數(shù)和非成員函數(shù)都可以直接訪問2.類成員在派生類中的訪問控制規(guī)則基類成員的存取說明符派生方式public派生protected派生private派生Private在派生類中被隱藏在派生類中被隱藏在派生類中被隱藏Protected派生類中為protected派生類中為protected派生類中為privatePublic派生類中為public派生類中為protected派生類中為private注意:不管是何種派生,基類的private成員永遠都不能被其派生類直接訪問,但可以通過基類的public和protected成員函數(shù)訪問。

8.3派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)8.3.1派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的聲明類的構(gòu)造函數(shù)是類的一種特殊的成員函數(shù),它的作用主要是為對象分配內(nèi)存、進行初始化;而析構(gòu)函數(shù)它的作用與構(gòu)造函數(shù)相反。派生類的構(gòu)造函數(shù)聲明格式如下:派生類的構(gòu)造函數(shù)名稱(參數(shù)表):基類的構(gòu)造函數(shù)名(參數(shù)表){ //… //派生類構(gòu)造函數(shù)體}classPoint{intx,y; public: Point(inta,intb) //基類的構(gòu)造函數(shù) { x=a; y=b; cout<<”ConstructingPointclass\n”; } ~Point() //基類的析構(gòu)函數(shù) { cout<<”DestructingPointclass\n”;}};classCircle:publicPoint{ doubleradius; public: Circle(doubler,inta,intb):Point(a,b)//派生類的構(gòu)造函數(shù) { radius=r; cout<<”ConstructingCircleclass\n”; } ~Circle() //派生類的析構(gòu)函數(shù) { cout<<”DestructingCircleclass\n”; }};派生類中含有對象成員時,其構(gòu)造函數(shù)的聲明格式如下:

派生類的構(gòu)造函數(shù)名稱(參數(shù)表):基類的構(gòu)造函數(shù)名(參數(shù)表),對象成員名1(參數(shù)表),…對象成員名N(參數(shù)表){ //… //派生類構(gòu)造函數(shù)體}classCircle2:publicPoint{ doubleradius; PointP1; public:Circle2(doubler,inta,intb):Point(a,b),P1(a,b) //派生類的構(gòu)造函數(shù),定義時//指定了基類的構(gòu)造函數(shù)和對象成員P1的構(gòu)造函數(shù) { radius=r; cout<<”ConstructingCircle2class\n”; } ~Circle2() //派生類的析構(gòu)函數(shù) { cout<<”DestructingCircle2class\n”; }};8.3.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的構(gòu)造規(guī)則

1.基類具有顯式的構(gòu)造函數(shù)時(1)基類具有不帶參數(shù)的構(gòu)造函數(shù)派生類既可以自己不定義構(gòu)造函數(shù),也可以根據(jù)需要定義自己的構(gòu)造函數(shù),構(gòu)造函數(shù)可以帶參數(shù)也可以省略,在派生類中定義構(gòu)造函數(shù)時還可省略“:基類構(gòu)造函數(shù)名(參數(shù)表)”。(2)基類僅有帶參數(shù)的構(gòu)造函數(shù)派生類必須顯式的定義其構(gòu)造函數(shù),并在聲明時指定其基類的某一構(gòu)造函數(shù)和參數(shù)表,把參數(shù)傳遞給基類構(gòu)造函數(shù)。2.基類具有隱式的構(gòu)造函數(shù)時當(dāng)基類沒有顯式的定義(即隱式的定義)構(gòu)造函數(shù)時,派生類可以根據(jù)需要定義自己的構(gòu)造函數(shù),派生類構(gòu)造函數(shù)的參數(shù)表、基類的構(gòu)造函數(shù)名和參數(shù)表都可以根據(jù)需要省略。8.3.3派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用順序1.構(gòu)造函數(shù)的調(diào)用順序派生類對象創(chuàng)建的時候,構(gòu)造函數(shù)的執(zhí)行順序為:(1)基類的構(gòu)造函數(shù)(2)對象成員的構(gòu)造函數(shù)(3)派生類自身的構(gòu)造函數(shù)2.析構(gòu)函數(shù)的調(diào)用順序與構(gòu)造函數(shù)的調(diào)用順序正好相反。即

(1)派生類自身的析構(gòu)函數(shù)(2)對象成員的構(gòu)造函數(shù)(3)基類的析構(gòu)函數(shù)【例8.6】派生類Circle2的構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序//…Point和Circle2類的定義main(){ Circle2C1(0.0,1,1); cout<<”-------------programline----------------\n”; return0;}8.4多重繼承8.4.1多重繼承的聲明前面討論的是單繼承,即一個類是從一個基類派生而來的。在C++中還允許從多個基類中派生出新的子類,這種派生方法稱為多重繼承(或多基派生)。這一強大的派生功能可以大大提高軟件重用的靈活性。聲明的格式如下:class派生類名:派生存取說明符(可省)1基類名1,…,派生存取說明符N基類名N{ //派生類新增的數(shù)據(jù)成員和成員函數(shù)};【例8.7】多重繼承的聲明#include<iostream.h>classCircle1//基類Circle1{protected:intr;public:voidsetx(intx){r=x;}voiddraw(){ cout<<"drawing…\n";}};classCircle2//基類Circle2{protected:intr;public:voidsetx(intx){r=x;}voidwrite(){ cout<<"writing…\n";}};classCircle:publicCircle1,publicCircle2//類Circle公有繼承了Circle1和Circle2{public:voidshow(){ cout<<"showing…\n";}};voidmain(){Circlecc;cc.draw();cc.write();cc.show();}8.4.2多重繼承的幾點說明1.在多重繼承中派生類成員的訪問控制規(guī)則與單一繼承規(guī)則相同。2.多重繼承的構(gòu)造函數(shù)與析構(gòu)函數(shù)定義與單一繼承相似,只是在構(gòu)造函數(shù)定義時N個基類的構(gòu)造函數(shù)之間用逗號分隔。3.多重繼承雖然功能強大,但也容易造成系統(tǒng)的復(fù)雜性,設(shè)計時務(wù)必正確和謹(jǐn)慎,能用單一繼承時盡量不用多重繼承。4.多重繼承容易產(chǎn)生模糊性,在引用時要注意例如前面例8.7如果按照下面來引用:voidmain(){Circlecc;cc.setx(10);//Circle1的setx還是Circle2的setx?}

voidmain(){Circlecc;cc.Circle1::setx(10);//說明是Circle1中的r為10}8.4.3虛基類

1.虛基類的概念當(dāng)在多條繼承路徑上有一個公共的基類,在這些路徑中的某幾條匯合處,這個公共的基類就會產(chǎn)生多個實例(或多個副本),若只想保存這個基類的一個實例,可以將這個公共基類說明為虛基類.

2.虛基類的聲明class派生類名:virtual派生存取說明符(可?。┨摶惷鹻 //派生類新增的數(shù)據(jù)成員和成員函數(shù)};3.虛基類的初始化虛基類初始化時,構(gòu)造函數(shù)的調(diào)用順序規(guī)則:(1)同一層派生中包含多個虛基類時,虛基類的構(gòu)造函數(shù)按它們派生時聲明的先后次序調(diào)用。(2)如某虛基類是由實基類派生而來,則先調(diào)用此實基類的構(gòu)造函數(shù),再調(diào)用虛基類的構(gòu)造函數(shù),最后才是派生類的構(gòu)造函數(shù)。(3)若同一層派生中,同時存在虛基類與實基類,應(yīng)先調(diào)用虛基類的構(gòu)造函數(shù),再調(diào)用實基類的構(gòu)造函數(shù),最后調(diào)用派生類的構(gòu)造函數(shù)。4.虛基類的作用虛基類的作用就是為其他類提供一個合適的基類,以便派生類可以從它那里繼承和實現(xiàn)所需的接口。在多重繼承時,當(dāng)派生類的多個基類有一個共同的基類時,為防止產(chǎn)生二義性問題可使用虛基類方法。注意:虛基類并不是在聲明基類時聲明的,而是在聲明派生類時,指定繼承方式時聲明的。因為一個基類可以在生成一個派生類時作為虛基類,而在生成另一個派生類時不作為虛基類。【例8.11】存在二義性的虛基類多重派生#include<iostream.h>classBase //基類{ protected: intb;public:Base() {b=1;cout<<”ConstructingBaseclass”<<endl; }};classBase1:publicBase//基類1從Base派生{ public:Base1() {cout<<”ConstructingBase1class”<<endl;cout<<”Baseb=”<<b<<endl; }};classBase2:publicBase //基類2從Base派生{ public:Base2() {cout<<”ConstructingBase2class”<<endl;cout<<”Baseb=”<<b<<endl; }};classDerived:publicBase1,Base2//從兩個基類base1和base2多重派生出子類{ public:Derived() { cout<<”ConstructingDerivedclass”<<endl;cout<<”Baseb=”<<b<<endl; }};main(){ DerivedD1; return0;}改成如下語句:classBas

溫馨提示

  • 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)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論