• /  63
  • 下載費用: 9.90積分  

C++課件教學作者邱志杰第四章_繼承與派生.ppt

'C++課件教學作者邱志杰第四章_繼承與派生.ppt'
第四章 繼承與派生丘志杰電子科技大學計算機學院**派生類的引入C++的類提供了良好的模塊分解技術,也具有可重用軟件所期望的品質:它們是相似一致的模塊,通過信息隱藏,將它們的接口和實現清楚地分開來。我們還希望在類的基礎上能取得更好的可重用性和可擴充性的目標。面向對象的繼承技術提供了實現上述目標的有力手段?,F實中的繼承與派生自然界中繼承的概念非常普遍。哺乳動物貓、狗都屬于哺乳動物,具備胎生、哺乳、恒溫等特征,但又具有各自的特性。**再來看一個現實世界中的例子:Rectangle Square Diamond ParallelogramQuadrangle四邊形是一個基本概念,矩形、正方形、菱形和平行四邊形都屬于四邊形,它們繼承了四邊形的所有屬性,但又擴充了各自的特性。**從上面的例子可以看出:派生:而且子代可以擁有父代沒有的特性,這是可擴充的概念。繼承:一旦指定了某種事物父代的本質特征,那么它的子代將會自動具有那些性質。這就是一種樸素的可重用的概念。**從軟件設計的角度來看:基于已有的類,可以建立新的類。這個新的類既重用已有類的功能,又擴展了新的功能。類是某類事物共同特性的體現,它對外提供了特定的功能。繼承定義了類如何相互關聯,共享特性。**C++的繼承關系繼承就是在一個已經存在的類的基礎上建立另一個新的類?;惻缮愐汛嬖诘念惙Q為“基類”或“父類”,新建立的類稱為“派生類”或“子類”,如圖所示:**單繼承和多繼承單繼承:派生類只有一個直接基類ABC單繼承XYZ多繼承多繼承:派生類有多個直接基類**單繼承派生類定義單繼承派生類的語法格式:class 派生類名 : 基類名{ ……//派生類新添加的成員};公有繼承是最常用的方式,它建立了一種“is-a-kind-of”關系。public、private、protected**舉例:商場的購物卡-1具有的信息:卡號、剩余金額可進行的操作:獲取卡號、獲取當前余額、消費不記名購物卡會員購物卡具有的信息:身份證號、姓名、電話可進行的操作:獲取/修改身份證號、姓名、電話等信息**單繼承派生類的構造函數派生類對象數據成員的構成:從基類繼承過來的數據成員派生類自定義的數據成員如何初始化這幾部分數據成員呢?基本數據類型類類型**單繼承派生類的構造函數派生類構造函數(參數表):基類構造函數(參數表), 對象成員1(參數表), …… 對象成員n(參數表),{ ……//初始化自定義數據成員}如果基類使用的是缺省的構造函數或不帶參數的構造函數,那么在初始化列表中可以省略“基類構造函數(參數表)“這一項。如果沒有對象成員,那么在初始化列表中可以省略“對象成員(參數表)“這一項。**構造函數的調用順序如下:構造函數和析構函數的調用順序先調用基類構造函數;再調用對象成員所屬類的構造函數;最后調用派生類構造函數;析構函數的調用順序如下:再調用對象成員所屬類的析構函數;先調用派生類的析構函數;最后調用基類的析構函數;**舉例:商場的購物卡-2具有的信息:卡號、剩余金額可進行的操作:獲取卡號、獲取當前余額、消費不記名購物卡會員購物卡具有的信息:身份證號、姓名、電話可進行的操作:獲取/修改身份證號、姓名、電話等信息,能夠充值**保護成員的引入C++專門設置了保護成員,即用protected關鍵字說明的成員。其特性:能夠被基類和派生類所訪問。和私有成員一樣,類外不能訪問。**舉例:商場的購物卡-3具有的信息:卡號、剩余金額可進行的操作:獲取卡號、獲取當前余額、消費不記名購物卡會員購物卡具有的信息:身份證號、姓名、電話可進行的操作:獲取/修改身份證號、姓名、電話等信息,能夠充值,消費能夠打折,能積分**公有派生類class 派生類名 : public 基類名{ ……//派生類新添加的成員};基類的成員在公有派生類中的引用權限基類公有成員私有成員保護成員公有派生類公有成員不可訪問成員保護成員不可訪問成員在類外不能被直接訪問。在派生類的類內不能被直接訪問**派生類的功能主要通過以下方式來體現:派生類的特性吸收基類成員添加新成員改造基類成員從編碼的角度來看,派生類從基類中以較低的代價換來了較大的靈活性:派生類可以對繼承的屬性進行擴展、限制或改變。一旦產生了可靠的基類,只需要調試派生類中所作的修改即可。**虛函數和多態性重載普通的成員函數的兩種方式:在同一個類中重載:重載函數是以參數特征區分的。派生類重載基類的成員函數: 由于重載函數處在不同的類中,因此它們的原型可以完全相同。以上兩種重載的匹配都是在編譯的時候靜態完成的。**重載是一種簡單形式的多態。虛函數提供的是一種動態綁定的機制。C++提供另一種更加靈活的多態機制:虛函數。虛函數允許函數調用與函數體的匹配在運行時才確定。**賦值兼容規則在公有派生方式下,派生類對象可以作為基類對象來使用,具體方式如下:Base Bobj; Derived Dobj;//派生類的對象可以直接賦值給基類的對象Bobj=Dobj;//基類對象的引用可以引用一個派生類對象Base &refB=Dobj;//基類對象的指針可以指向一個派生類對象Base *pB=&Dobj;為什么是“派生類對象->基類對象”,而不是“基類對象->派生類對象”?**v1v2v1v2v3v4基類對象派生類對象基類對象和派生類對象的內存布局方式當一個派生類對象直接賦值給基類對象時,不是所有的數據都賦給了基類對象,賦予的只是派生類對象的一部分。這部分叫做派生類對象的“切片”(sliced)。派生類擁有從基類繼承過來的成員**簡單的例子class Base{public: void Print(){ cout<<"I am Base\n"; };};class Derived:public Base{public: void Print(){ cout<Print(); p=&derived; p->Print(); }//調用的是基類的Print//調用的是基類的Print**通過基類引用或指針所能看到的是一個基類對象,派生類中的成員對于基類引用或指針來說是“不可見的”。Base::PrintDerived::Printp對于p是不可見的**為了達到上述目的,我們可以利用C++的虛函數機制,將基類的Print說明為虛函數形式。這樣就可以通過基類引用或指針來訪問派生類中的Print。我們能不能“通過基類引用或指針來訪問派生類的成員”呢?**簡單的例子(續):使用虛函數class Base{public: virtual void Print(){ cout<<"I am Base\n"; };};class Derived:public Ba。省略部分。 對象成員1(參數表3), 對象成員2(參數表4), …{ //派生類新添加的成員}**派生類構造函數的執行順序:先執行所有基類的構造函數(按這些基類被繼承時聲明順序依次執行基類1、基類2的構造函數)。最后執行派生類本身的構造函數。再執行對象成員所屬類的構造函數(按照這些對象成員在類中定義的順序)。**多繼承中的二義性問題在多繼承中,一個類不可以重復成為另一個類的直接基類,但可以多次成為間接基類。此時派生類訪問基類成員時可能出現二義性。訪問共同基類的成員時可能出現二義性。訪問不同基類的具有相同名字成員時可能出現二義性。**訪問不同基類同名成員時的二義性 class A{ public: int value; void f(){};};class B{ public: int value; void f(){}; void g(){};};class C: public A, public B{ public: void g(){}; void h(){};};void main(){ C C1; C1.f(); C1.value=9;}//出現二義性//出現二義性解決辦法是用類名對成員加以限定,例如: C1.A::f(); 或者C1.B::f(); C1.A::value=9; 或者C1.B::value=9;**訪問共同基類成員時的二義性 class A{ public: int a; void g( ){};};class B1: public A{ int b1;};class B2: public A{ int b2;};class C: public B1, public B2{ int c; public: int f(){};};void main(){ C Cobj; Cobj.a=8; Cobj.A::a=9; Cobj.g( );}//出現二義性//出現二義性//出現二義性解決辦法:Cobj.B1::a=9;或 Cobj.B2::a=9;**以上類的關系如下圖所示:A(a,g())B1(b1)A(a,g())B2(b2)C(f(),c)類A 是派生類C 兩條繼承路徑上的一個公共基類,因此這個公共基類會在派生類對象中產生兩個基類子對象。雖然可以通過類限定符的方式避免二義性,但問題的關鍵在于我們不需要在派生類對象中存在多個基類對象的拷貝!如果要使這個公共基類在派生類中只產生一個基類子對象,則需要將這個基類設置為虛基類。**例子:虛基類的使用 class A{ public: int a; void g( ){};};class B1: virtual public A{ int b1;};class B2: virtual public A{ int b2;};class C: public B1, public B2{ int c; public: int f(){};};void main(){ C Cobj; Cobj.a=8; //或Cobj.A::a=9; Cobj.g( );}**A(g(),a)B1(b1)B2(b2)C(f(),c)類A,B1,B2 和C之間的關系如下圖所示:引進虛基類的目的是為了解決二義性問題,使公共基類在其派生類對象中只產生一個基類子對象。**請比較下面兩種情況class C: public B1, public B2{ int c; public: int f();};class C: public B2, public B1{ int c; public: int f();};對于類C而言,類A是類B2的“假”基類,是類B1的“真”基類。對于類C而言,類A是類B1的“假”基類,是類B2的“真”基類。A(g(),a)B1(b1)B2(b2)C(f(),c)A(g(),a)A(g(),a)B1(b1)B2(b2)C(f(),c)A(g(),a)因此,虛基類只是一個相對的概念。**虛基類對象的初始化虛基類構造函數的調用次序如下:虛基類的構造函數在非虛基類之前調用。若虛基類由非虛基類派生,則遵守先調用基類構造函數,再調用派生類構造函數的規則。若在同一層次中包含多個虛基類,那么虛基類構造函數按它們說明的次序調用。**例子class base{…};class bas2{…};class level1 : public base2, vitrual public base{…};class level2 : public base2, vitrual public base{…};class toplevel : public level1, vitrual public level2{…};當聲明toplevel類的對象時,構造函數的調用次序為: base base2 level2 base2 level1 toplevel**私有派生類class 派生類名 : private 基類名{ ……//派生類新添加的成員};基類的成員在私有派生類中的引用權限基類公有成員私有成員保護成員私有派生類私有成員不可訪問成員私有成員**舉例:私有派生class Base{ int v1;public: int v2; Base(int a=0,int b=0){ v1=a;v2=b; }};class Derived : private Base{ int v3;public: int v4; Derived(int a=0,int b=0){ v3=a;v4=b; } void func(){ int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; }};void main( ){ Derived obj(5,6); obj.v2=8;}//錯誤//錯誤**公有派生和私有派生的比較雖然派生類繼承了基類所有的成員,但是對于派生類來說,基類的私有成員是不可見的,因此不能被派生類所訪問?;惞谐蓡T私有成員保護成員公有派生類公有成員不可訪問成員保護成員私有派生類私有成員不可訪問成員私有成員**保護派生類class 派生類名 : protected 基類名{ ……//派生類新添加的成員};基類的成員在保護派生類中的引用權限基類公有成員私有成員保護成員保護派生類保護成員不可訪問成員保護成員**小結不同的繼承方式,子類對基類中的成員的訪問權限如下表所示:基類公有成員私有成員保護成員公有派生類公有成員不可訪問成員保護成員保護派生類保護成員不可訪問成員保護成員私有派生類私有成員不可訪問成員私有成員
關 鍵 詞:
第四 教學 c++ 作者 繼承 派生
 天天文庫所有資源均是用戶自行上傳分享,僅供網友學習交流,未經上傳用戶書面授權,請勿作他用。
關于本文
本文標題:C++課件教學作者邱志杰第四章_繼承與派生.ppt
鏈接地址: http://www.476824.live/p-51617169.html
關于我們 - 網站聲明 - 網站地圖 - 資源地圖 - 友情鏈接 - 網站客服點擊這里,給天天文庫發消息,QQ:1290478887 - 聯系我們

本站為“文檔C2C交易模式”,即用戶上傳的文檔直接賣給(下載)用戶,本站只是中間服務平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有【成交的100%(原創)】。本站是網絡服務平臺方,若您的權利被侵害,侵權客服QQ:1290478887 歡迎舉報。

[email protected] 2017-2027 http://www.476824.live 網站版權所有

粵ICP備19057495號 

收起
展開
球探网即时蓝球比分 云南11选五前三 河北快三投注 江苏体彩7位数历史开奖 天津时时彩20分钟开奖 云南十一选五详细走势图 安徽十一选五的开奖 湖北福30选5开奖结果 股市大盘走势图分析 今日河南泳坛夺金 三十三码的鞋内长多少