版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第 12 章 繼承和派生12.1 繼承的基本概念 12.2 單一繼承 12.3 多重繼承 12.4 基類成員的初始化 12.5 二義性和支配規(guī)則 12.6 虛基類 12.7 訪問(wèn)基類成員和訪問(wèn)對(duì)象成員的成員 12.8 賦值兼容 第 12 章 繼承和派生 繼承提供了在已有類的基礎(chǔ)上開(kāi)發(fā)出新類的機(jī)制,可以節(jié)省重復(fù)代碼的編寫(xiě)工作,是軟件重用的基礎(chǔ)。 B AA派生類是對(duì)基類的擴(kuò)充12.1 繼承的基本概念已知一個(gè)類A,對(duì)A類加以擴(kuò)展,即增加一些屬性和行為,構(gòu)成一個(gè)新類B,此時(shí)B類將A類已有的屬性和行為繼承下來(lái)。稱類 B 繼承了 A ,或稱類 A 派生了 B 。A :父類,基類 BaseClassB :子
2、類,派生類 DerivedClass在校人員類學(xué)生類職工類( 屬性:姓名,年齡,身高 ) 增加屬性: 學(xué)號(hào) 成績(jī) 增加屬性: 部門(mén) 工資 單一繼承多重繼承圓柱體類 圓類 高度類 組合(屬性: 圓心坐標(biāo),半徑) (屬性: 高度)屬性: 圓心坐標(biāo),半徑 ,高度在C+中,有兩種繼承方式:?jiǎn)我焕^承和多重繼承。 12.2 單一繼承定義派生類的一般格式:class : private: / 私有成員說(shuō)明 . public: / 公有成員說(shuō)明 . protected: / 保護(hù)成員說(shuō)明 . ; 繼承方式:public 公有繼承(派生) private 私有繼承(派生) protected 保護(hù)繼承(派生)定
3、義派生類新成員12.2.1 公有繼承(派生) A B class A . ;class B: public A / 公有繼承A . ;A 類中的 public 和 protected 成員,在B 中仍然保持其原訪問(wèn)特性。雖然A中的私有成員也被繼承下來(lái)了,但在B中不可直接訪問(wèn)。A 中的: 在 B 中: 在B的類外(通過(guò)對(duì)象) private 成員 不可訪問(wèn) 不可訪問(wèn)public成員 仍為 public 成員 可訪問(wèn)protected成員 仍為 protected 成員 不可訪問(wèn)相當(dāng)于對(duì)B類做如下定義: class B: private: int bx;protected: int ay; int
4、 by;public: int az; int bz; void f1( ).; int Getax( ). void Setax( int x ) ax = x; void f2( ).; float f3( ).;private int ax;例如: 繼承關(guān)系如下:class A private: int ax;protected: int ay;public: int az; void f1( ).; int Getax( )return ax; void Setax( int x ) ax = x; ;class B: public A private: int bx;protecte
5、d: int by;public: int bz; void f2( ).; float f3( ).;藍(lán)色斜體是從A類繼承的成員在 B 的成員函數(shù)中可直接訪問(wèn)A類的ay,az,f1( ),Getax( ),Setax( )相當(dāng)于對(duì)B類做如下定義: class B: private: int bx;protected: int ay; int by;public: int az; int bz; void f1( ).; int Getax( ). void Setax( int x ) ax = x; void f2( ).; float f3( ).;private int ax;例如:
6、繼承關(guān)系如下:class A private: int ax;protected: int ay;public: int az; void f1( ).; int Getax( )return ax; void Setax( int x ) ax = x; ;class B: public A private: int bx;protected: int by;public: int bz; void f2( ).; float f3( ).;在B類中不可直接訪問(wèn)A類的成員ax可通過(guò) Getax( )、Setax( )訪問(wèn)A類的私有成員 ax 的值注意:在main( )函數(shù)中,只定義一個(gè)Cir
7、cle類對(duì)象:int main( )Circle c(0, 0, 2);c.ShowCircle( );c.Move(2, 2);c.ShowCircle( );c.Setxy(0, 0); /重新置圓心坐標(biāo) c.Setr(1); /重新置半徑值c.ShowCircle( );return 0; 使用一個(gè)Circle類對(duì)象 c 時(shí),感覺(jué)Circle類是一個(gè)完整的類,就象 Point 類不存在一樣。 如Setxy( ) 函數(shù),它是在基類中被定義的,現(xiàn)在它就是Circle類的成員了,但在Circle類中并沒(méi)有寫(xiě)出它的實(shí)現(xiàn)函數(shù),代碼是被繼承下來(lái)的。例12.1見(jiàn) “第12章 繼承和派生(例子).doc
8、x” 面向?qū)ο蟪绦蛟O(shè)計(jì)中繼承性的優(yōu)點(diǎn)就在于此,系統(tǒng)提供了相當(dāng)多的已定義好的基類,用戶可以根據(jù)具體的應(yīng)用,在已有類的基礎(chǔ)上構(gòu)架新類,在派生類中,可以直接使用父類部分的代碼,但卻不需要重新編寫(xiě)父類的代碼。這樣可以加速軟件開(kāi)發(fā)的速度,保障軟件開(kāi)發(fā)的質(zhì)量。繼承性是軟件重用的基礎(chǔ)。 在一個(gè)類上僅構(gòu)架一個(gè)新類,意義并不大。但如果構(gòu)架多個(gè)新類,那么就可以減少大量相同代碼的重復(fù)編寫(xiě)工作。如從一個(gè)“點(diǎn)”類可以派生出“線”類、“圓”類、“長(zhǎng)方形”類等。 從本例中,還可以看出另一個(gè)問(wèn)題:為了實(shí)現(xiàn)數(shù)據(jù)保護(hù),在基類中將 x, y 定義為私有成員,但是帶來(lái)一個(gè)問(wèn)題,即在派生類中需通過(guò)公有成員函數(shù)Getx( ) ,Setx
9、y(x1, y1) 等來(lái)訪為基類的私有成員。 如果在基類中將 x, y 定義為保護(hù)成員,則公有繼承后,在派生類中x, y 仍然是保護(hù)成員,在派生類內(nèi)可直接訪問(wèn)。這樣既可以保護(hù)基類數(shù)據(jù)成員,又可以在派生類中提供訪問(wèn)基類數(shù)據(jù)成員的方便性。12.2.2 私有繼承(派生) A B class A . ;class B: private A / 私有繼承A . 將 A 中的 public 和 protected 成員均變成了B 的 private 成員。同理,A中的私有成員被繼承下來(lái)了,但在B中不可直接訪問(wèn),A 中的: 在 B 中: 在類外(類B的對(duì)象中) private 成員 不可訪問(wèn) 不可訪問(wèn)pub
10、lic成員 變?yōu)?private 成員 不可訪問(wèn)protected成員 變?yōu)?private 成員 不可訪問(wèn)相當(dāng)于對(duì)B類做如下定義: class B: private: int bx; int ay; int az; void f1( ).; int Getax( ). void Setax( int x ) ax = x; protected: int by;public: int bz; void f2( ).; float f3( ).;private int ax;例如: 繼承關(guān)系如下:class A private: int ax;protected: int ay;public:
11、int az; void f1( ).; int Getax( )return ax; void Setax( int x ) ax = x; ;class B: private A private: int bx;protected: int by;public: int bz; void f2( ).; float f3( ).;藍(lán)色斜體是從A類繼承的成員在 B 的成員函數(shù)中可直接訪問(wèn)A類的ay,az,f1( ),Getax( ),Setax( )相當(dāng)于對(duì)B類做如下定義: class B: private: int bx; int ay; int az; void f1( ).; int
12、Getax( ). void Setax( int x ) ax = x; protected: int by;public: int bz; void f2( ).; float f3( ).;private int ax;例如: 繼承關(guān)系如下:class A private: int ax;protected: int ay;public: int az; void f1( ).; int Getax( )return ax; void Setax( int x ) ax = x; ;class B: private A private: int bx;protected: int by;
13、public: int bz; void f2( ).; float f3( ).;在B類中不可直接訪問(wèn)A類的成員ax可通過(guò) Getax( )、Setax( )訪問(wèn)A類的私有成員 ax 的值12.2.3 保護(hù)繼承(派生) A B class A . ;class B: protected A / 保護(hù)繼承A . A 中的: 在 B 中: 在類外(類B的對(duì)象中) private 成員 不可訪問(wèn) 不可訪問(wèn)public成員 變?yōu)?protected 成員 不可訪問(wèn)protected成員 變?yōu)?protected成員 不可訪問(wèn)將 A 中的 public 和 protected 成員均變成了B 的 pr
14、otected 成員。同理,A中的私有成員被繼承下來(lái)了,但在B中不可直接訪問(wèn),由于“私有繼承” 和“保護(hù)繼承”用得不多,在這里不再詳細(xì)敘述了。 無(wú)論何種繼承方式,private成員是無(wú)法在派生類中被直接訪問(wèn)的。而對(duì)于protected成員,根據(jù)不同的派生方式,protected成員的直接訪問(wèn)特性可以被(或不被)傳遞到派生類的派生類中。 12.2.4 private成員和protected成員的區(qū)別 1對(duì)于公有派生,基類的protected成員在派生類中依然保持protected屬性。2對(duì)于私有派生,基類的protected成員在派生類中變成了private成員,此時(shí)基類的protected成員
15、就再也無(wú)法在派生類的派生類中被直接訪問(wèn)了。在繼承或派生鏈中,一旦出現(xiàn)私有繼承,則父類的成員的“類內(nèi)直接訪問(wèn)特性”就無(wú)法在后面的派生中傳遞下去。3對(duì)于保護(hù)派生,基類的protected成員在派生類中依然保持protected屬性,此時(shí)情況與公有派生類似。類中protected成員的優(yōu)點(diǎn)是:既可以在本類中實(shí)現(xiàn)數(shù)據(jù)的隱藏(在類外不可被直接訪問(wèn)),又可以將其類內(nèi)直接訪問(wèn)特性傳遞到派生類中(在派生類中可直接訪問(wèn))。但private成員只能實(shí)現(xiàn)本類中的數(shù)據(jù)隱藏,而不能將其類內(nèi)直接訪問(wèn)特性傳遞到派生類中。 12.3 多重繼承一般格式:class : , , /以下定義派生類新成員 private: / 私有
16、成員說(shuō)明 . public: / 公有成員說(shuō)明 . protected: / 保護(hù)成員說(shuō)明 . ;多個(gè)基類派生一個(gè)類多重繼承Circle 類Point類 Radius類 組合再次說(shuō)明保護(hù)成員的優(yōu)點(diǎn)例12.2 見(jiàn) “第12章 繼承和派生(例子).docx”注意例12.2的D行,若一個(gè)類是由多個(gè)基類派生出來(lái)的,則在定義派生類構(gòu)造函數(shù)時(shí),應(yīng)調(diào)用基類的構(gòu)造函數(shù),以初始化基類成員。 12.4 基類成員的初始化12.4.1 基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用順序 派生類構(gòu)造函數(shù)的一般格式:ClassName : ClassName(args) : Base1(arg1) , Base2(arg2) , . B
17、asen(argn) ;其中ClassName是派生類名,Base1、Base2、.Basen為基類的類名。args是派生類自身的構(gòu)造函數(shù)的形參列表,arg1、arg2、.argn是調(diào)用基類構(gòu)造函數(shù)的實(shí)參列表。 析構(gòu)函數(shù)的調(diào)用順序?yàn)椋海ㄏ喾矗┫葓?zhí)行派生類自身的析構(gòu)函數(shù)體、然后按 Basen( ) 、.Base2( ) 、Base1( )例12.3 見(jiàn) “第12章 繼承和派生(例子).docx”構(gòu)造函數(shù)的調(diào)用順序?yàn)椋?Base1( )、 Base2( )、. Basen( )、最后執(zhí)行。 在例12.3中:調(diào)用基類的構(gòu)造函數(shù)的順序并不是B行的書(shū)寫(xiě)順序決定的,而是A行定義派生類時(shí)的派生順序決定的,即
18、使將B行改寫(xiě)成Derived(int x, int y, int z) : Base2(y), Base1(x),程序的運(yùn)行結(jié)果依然不變。 12.4.2 對(duì)象成員構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用順序 例12.4 見(jiàn) “第12章 繼承和派生(例子).docx”或見(jiàn)下一頁(yè)簡(jiǎn)化例子:若派生類中包含對(duì)象成員,則在派生類的構(gòu)造函數(shù)的初始化成員列表中:不僅要列舉基類的構(gòu)造函數(shù),而且要列舉對(duì)象成員的構(gòu)造函數(shù)class Base1 int data1;public: Base1(int a)data1=a; .;class Base2 int data2; public: Base2(int a)data2=a; .
19、 ;class Derived: public Base1, public Base2 /公有繼承基類 int d; Base1 b1, b2; /對(duì)象成員public: Derived(int a, int b):Base1(a), Base2(20),b1(200),b2(a+b) d=a; .先調(diào)用基類的構(gòu)造函數(shù)再調(diào)用對(duì)象成員的構(gòu)造函數(shù)最后執(zhí)行對(duì)象自身的構(gòu)造函數(shù)問(wèn)題見(jiàn)下頁(yè)問(wèn)題:對(duì)本例,一個(gè)Derived類的對(duì)象有幾個(gè)數(shù)據(jù)成員?(包括自身具備的、和繼承來(lái)的? )返回12.5 二義性和支配規(guī)則12.5.1 二義性(多重繼承帶來(lái)的訪問(wèn)沖突)例12.5class A protected: int
20、 x;public: A(int a) x=a; .;class B protected: int x;public: B(int a) x=a; .;class C: public A, public B /公有繼承 A 和 B int y;public: void Setx(int a) x=a; .;當(dāng)基類 A和 B 中出現(xiàn)兩個(gè)同名的成員 x 時(shí),在派生類中訪問(wèn) x 出現(xiàn)二義性問(wèn)題:一個(gè)類C的對(duì)象有幾個(gè)數(shù)據(jù)成員?class A protected: int x;public: A(int a) x=a; .;class B protected: int x;public: B(int a
21、) x=a; .;class C: public A, public B /公有繼承 A 和 B int y;public: void Setx(int a) x=a; .;解決辦法:將此句改為:A:x = a; 或 B:x = a;同理:解決基類同名成員函數(shù)的訪問(wèn)class C: public A, public B /公有繼承 A 和 Bint y;public:void SetAx(int a) A:x=a;/對(duì)類A中的x置值void SetBx(int a) B:x=a;/對(duì)類B中的x置值void Sety(int b) y=b; int Gety( ) return y; ;int
22、main( )C c1;c1.SetAx(35);c1.SetBx(45);c1.Sety(300);coutY=c1.Gety( )endl;return 0;例12.6 部分代碼,解決訪問(wèn)沖突 C A B 注意:如何解決沖突 (訪問(wèn)二義性)。當(dāng)把派生類作為基類,又派生出新的派生類時(shí),這種限定作用域的運(yùn)算符不能連續(xù)嵌套使用,如下形式的使用方式是不允許的: : : : 例12.7 見(jiàn) “第12章 繼承和派生(例子).docx”如何解決多層繼承中的沖突,請(qǐng)看下例:由于C+是通過(guò)作用域運(yùn)算符來(lái)解決訪問(wèn)二義性問(wèn)題,因此規(guī)定任一基類在派生類中只能被直接繼承一次,否則會(huì)造成成員名訪問(wèn)的沖突。例如:cla
23、ss A public: float x; .;class B: public A, public A /錯(cuò)誤的. ;B類的定義是錯(cuò)誤的,因?yàn)槿绻苯訌腁類繼承兩次,通過(guò)作用域運(yùn)算符就無(wú)法解決訪問(wèn)二義性問(wèn)題。 12.5.2 支配規(guī)則例12.8 支配規(guī)則示例 見(jiàn) “第12章 繼承和派生(例子).docx”問(wèn)題:類 C 有幾個(gè)數(shù)據(jù)成員?;惡团缮惓霈F(xiàn)同名成員時(shí),派生類成員訪問(wèn)優(yōu)先-支配規(guī)則12.6 虛基類 類D 基類B 基類C 基類A 基類A 如右圖的公有繼承關(guān)系中, 在類 D 中包含了基類 A 的 兩個(gè)拷貝。 在類 D 的成員函數(shù)中, 欲訪問(wèn) A 的成員 x , 則必須以 B:x 和 C:x
24、區(qū)分。 B DA C A一個(gè)D類對(duì)象的存儲(chǔ)空間 若欲使公共的基類A 在派生類中只有一個(gè)拷貝, 如右圖, 可將 A 說(shuō)明成虛基類。 說(shuō)明的方法: 繼承時(shí),在基類的類名前 加上關(guān)鍵詞:virtual 類D 基類B 基類C 基類A 例12.10 虛基類的例子見(jiàn)下頁(yè): B D C A一個(gè)D類對(duì)象的存儲(chǔ)空間 class A protected: int x; public: A(int a=0) x=a; ;class B: virtual public A protected: int y; public: B(int a=0, int b=0):A(a) y=b; ;class C: public
25、virtual A protected: int z; public: C(int a=0, int c=0):A(a) z=c; ;注意: virtual 的位置。class D: public B, public C protected: int k; B(a1, b), C(a2, c), k(d) public: D(int a1=0, int a2=0, int b=0, int c=0, int d=0) : void Show( )cout x= x , ; cout y= y , ;cout z= z , ;cout k= k endl;int main(void)D obj(
26、1, 1, 2, 3, 4);obj.Show( );return 0; 發(fā)揮 程序的運(yùn)行結(jié)果是:x=0, y=2, z=3, k=4問(wèn)題:類 D 有幾個(gè)數(shù)據(jù)成員?B 和 C 的構(gòu)造函數(shù)中,分別調(diào)用 A的構(gòu)造函數(shù),編譯器無(wú)法確定調(diào)用哪一個(gè)來(lái)初始化A,在這種情況下,約定直接調(diào)用 A 的缺省構(gòu)造函數(shù)。(即使 a1 和 a2 的值相等)如將G行改為:D(int a1=0, int a2=0, int b=0, int c=0, int d=0) : B(a1, b), C(a2, c), A(a1), k(d) /G 則程序的運(yùn)行結(jié)果變?yōu)椋?x=1, y=2, z=3, k=4 注意:如果派生類有多個(gè)基類,有些是虛基類有些是非虛基類。則基類構(gòu)造的調(diào)用順序是先調(diào)用虛基類的構(gòu)造函數(shù)再調(diào)用非虛基類的構(gòu)造函數(shù),并按照繼承順序調(diào)用。直接調(diào)用虛基類的構(gòu)造函數(shù)例12.11 見(jiàn) “第12章 繼承和派生(例子).docx”在成員函數(shù)中:(1) 使用基類的成員 (2) 使用對(duì)象成員的成員時(shí),情況不同12.7 訪問(wèn)基類成員和訪問(wèn)對(duì)象成員的成員class A public: int x; A(int
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《血友病的護(hù)理》課件
- 《行政許可法培訓(xùn)》課件
- 合肥市房屋租賃合同示范文本
- 工程施工合同約束條款的執(zhí)行力度
- 《氮?dú)馓幚淼奈kU(xiǎn)》課件
- 《蔬菜腌漬》課件
- 2025年吉林市考貨運(yùn)上崗證試答題
- 2025年酒泉b2從業(yè)資格證模擬考試題目
- 2025年曲靖貨運(yùn)從業(yè)資格證試題及答案
- 2025年天津從業(yè)資格貨運(yùn)資格考試題庫(kù)答案解析
- (正式版)JBT 9634-2024 汽輪機(jī)冷油器(管式)尺寸系列和技術(shù)規(guī)范
- 歐美電影文化智慧樹(shù)知到期末考試答案2024年
- 建筑工程制圖與識(shí)圖智慧樹(shù)知到期末考試答案2024年
- 會(huì)議運(yùn)營(yíng)與管理(雙語(yǔ))智慧樹(shù)知到期末考試答案2024年
- 24春國(guó)家開(kāi)放大學(xué)《鄉(xiāng)鎮(zhèn)行政管理》作業(yè)1-5參考答案
- 2024年一線及新一線城市職場(chǎng)人心理健康洞察報(bào)告
- 日本核廢水事件始末課件(圖文)
- 益生菌項(xiàng)目計(jì)劃書(shū)
- 2024年遼寧鐵道職業(yè)技術(shù)學(xué)院高職單招(英語(yǔ)/數(shù)學(xué)/語(yǔ)文)筆試歷年參考題庫(kù)含答案解析
- 《路德維希·費(fèi)爾巴哈和德國(guó)古典哲學(xué)的終結(jié)》導(dǎo)讀
- 新改版蘇教版六年級(jí)下冊(cè)科學(xué)全冊(cè)知識(shí)點(diǎn)(精編版)
評(píng)論
0/150
提交評(píng)論