第八章繼承和派生類_第1頁
第八章繼承和派生類_第2頁
第八章繼承和派生類_第3頁
第八章繼承和派生類_第4頁
第八章繼承和派生類_第5頁
已閱讀5頁,還剩28頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第二部分第二部分 C+C+面向對象程序設計面向對象程序設計 本章課件制作:關欣本章內容本章內容 繼承性、基類和派生類的基本概念繼承性、基類和派生類的基本概念 派生類的定義和派生類對象的組成派生類的定義和派生類對象的組成 派生類的構造函數和析構函數派生類的構造函數和析構函數 虛基類虛基類 賦值兼容規則賦值兼容規則8.1 繼承概述繼承概述 繼承:繼承:就是在原有類就是在原有類(稱為基類或父類稱為基類或父類)的基礎上的基礎上,經過適當擴充和完善經過適當擴充和完善建立新的類建立新的類(稱為派生類或子稱為派生類或子類類) 新的類不僅新的類不僅具有具有基類的特征,而且還可以基類的特征,而且還可以添加添加新

2、新的特征,同時能夠的特征,同時能夠繼續被繼承繼續被繼承而派生出新的類而派生出新的類 繼繼承的本質是創建新的類承的本質是創建新的類 1.繼承的定義繼承的定義 擴充和完善原有程序以適應新的需求擴充和完善原有程序以適應新的需求 提高軟件開發的效率提高軟件開發的效率,增加程序的重用性增加程序的重用性,減少減少代碼和數據的冗余度代碼和數據的冗余度2. 繼承的特點繼承的特點AB(1) B單重繼承單重繼承A(2) C多重繼承多重繼承A和和BACBABC(3) 多級繼承多級繼承(4) 混合繼承混合繼承ACBEFD3. 3種繼承關系種繼承關系8.2 基類和派生類基類和派生類 1.定義派生類的格式定義派生類的格式

3、class 派生類名派生類名: virtual 繼承方式繼承方式1 基類名基類名1, virtual 繼承方式繼承方式2 基類名基類名2, 派生類類體派生類類體 ; 派生類類體中未定義的成員函數的實現派生類類體中未定義的成員函數的實現 2. 3種繼承方式種繼承方式 public(公有繼承公有繼承) private(私有繼承私有繼承,缺省繼承方式缺省繼承方式) protected(保護繼承保護繼承) 不可直接訪問不可直接訪問privateprivateprivate不可直接訪問不可直接訪問protectedprotectedprotected不可直接訪問不可直接訪問protectedpublic

4、publicprivateprotectedpublic基類特性基類特性派生類特性派生類特性繼承方式繼承方式不同繼承方式下基類與派生類的特性不同繼承方式下基類與派生類的特性 2.1 public 公有繼承公有繼承 class A public: int k1; void f1(); protected: int j1; void g1(); private: int i1; void h1(); ; class B:public A public: int k2;程序說明:程序說明:派生類派生類B的成員函數的成員函數f2( )、g2( )和和h2( )中中,可直接訪問可直接訪問類類A的的k1、

5、f1( )、j1和和g1( ),但不能直接訪問類但不能直接訪問類A的的i1和和h1( ) 派生類派生類B的對象的對象僅可直接僅可直接訪問類訪問類A的的k1和和f1( ),而不能而不能直接訪問類直接訪問類A的任何保護成的任何保護成員和私有成員。員和私有成員。2.2 private 私有繼承私有繼承 class A public: int k1; void f1(); protected: int j1; void g1(); private: int i1 void h1(); ; class B: A public: int k2;程序說明:程序說明:派生類派生類B的成員函數的成員函數f2(

6、)、g2( )和和h2( )中中,可直接訪問可直接訪問類類A的的k1、f1( )、j1和和g1( ),但不能直接訪問類但不能直接訪問類A的的i1和和h1( ) 派生類派生類B的對象的對象不能直接不能直接訪問類訪問類A的任何保護成員和的任何保護成員和私有成員。私有成員。2.3 protected 保護繼承保護繼承 class A public: int k1; void f1(); protected: int j1; void g1(); private: int i1; void h1(); ; class B: protected A public: int k2;程序說明:程序說明:派生

7、類派生類B的成員函數的成員函數f2( )、g2( )和和h2( )中中,可直接訪問可直接訪問類類A的的k1、f1( )、j1和和g1( ),但不能直接訪問類但不能直接訪問類A的的i1和和h1( ) 派生類派生類B的對象的對象不能直接不能直接訪問類訪問類A的任何保護成員和的任何保護成員和私有成員。私有成員。3. 派生類對象的數據成員組成派生類對象的數據成員組成直接基類直接基類1數據成員數據成員(除靜態數據成員外除靜態數據成員外)直接基類直接基類2數據成員數據成員(除靜態數據成員外除靜態數據成員外).直接基類直接基類n數據成員數據成員(除靜態數據成員外除靜態數據成員外)子對象子對象1數據成員數據成

8、員(除靜態數據成員外除靜態數據成員外)子對象子對象2數據成員數據成員(除靜態數據成員外除靜態數據成員外).子對象子對象m數據成員數據成員(除靜態數據成員外除靜態數據成員外)派生類本身數據成員派生類本身數據成員(除靜態數據成員外除靜態數據成員外)class A public: int k1; void f1(); protected: int j1; void g1(); private: int i1; void h1();class B :public Apublic: void f2(); protected: int j2; Bj2C i3Ai1j1k1A a1i1j1k1A a2i1j

9、1k1B的子對象的子對象a2的數據成員的數據成員C的的數數據據成成員員B的的數數據據成成員員B的子對象的子對象a1的數據成員的數據成員B的直接基類的直接基類A的數據成員的數據成員例例 畫出下面程序中類畫出下面程序中類C對象對象obj1的組成結構圖。的組成結構圖。 8.3 派生類的構造函數與析構函數派生類的構造函數與析構函數 1. 派生類構造函數的一般形式派生類構造函數的一般形式派生類構造函數名派生類構造函數名(總參數表總參數表):直接基類初始化表直接基類初始化表,子對象初子對象初始化表始化表,派生類自身數據成員初始化表派生類自身數據成員初始化表 派生類構造函數體派生類構造函數體 直接基類初始化

10、表直接基類初始化表的形式為的形式為: 直接基類直接基類1構造函數構造函數 (參數表參數表1), 直接基類直接基類2構造函數構造函數 (參數表參數表2), 子對象初始化表子對象初始化表形式為形式為: 子對象名子對象名1(參數表參數表1),子對象名子對象名2(參數表參數表2), 派生類自身數據成員初始化表派生類自身數據成員初始化表形式為形式為: 數據成員名數據成員名1(參數參數1),數據成員名數據成員名2(參數參數2), 2. 派生類構造函數的執行順序派生類構造函數的執行順序 直接基類直接基類1數據成員數據成員(除靜態數據成員外除靜態數據成員外)直接基類直接基類2數據成員數據成員(除靜態數據成員外

11、除靜態數據成員外).直接基類直接基類n數據成員數據成員(除靜態數據成員外除靜態數據成員外)子對象子對象1數據成員數據成員(除靜態數據成員外除靜態數據成員外)子對象子對象2數據成員數據成員(除靜態數據成員外除靜態數據成員外).子對象子對象m數據成員數據成員(除靜態數據成員外除靜態數據成員外)派生類本身數據成員派生類本身數據成員(除靜態數據成員外除靜態數據成員外)各直接基類各直接基類 派生類自身數據成員派生類自身數據成員 各子對象各子對象(定義時的順序)(定義時的順序) (定義時的順序)(定義時的順序) #include class Base public: Base()a=0;coutBase缺

12、省缺省 Base(int i)a=i;coutBase構構 void print()couta=a int Geta()return a; private: int a; ; class Derived:public Base public: Derived()b=0;coutDeriv void print(); private: int b; 例例 單重繼承派生類構造函數示例單重繼承派生類構造函數示例 程序輸出結果程序輸出結果 :Base缺省構造函數缺省構造函數 Base缺省構造函數缺省構造函數 Derived缺省構造函數缺省構造函數 Base構造函數構造函數 Base構造函數構造函數 D

13、erived構造函數構造函數 a=0,b=0,Ba.a=0a=5,b=7,Ba.a=3 b 0Base Baa 0Base a 0d1組成結構圖組成結構圖b 7Base Baa 3Base a 5d2組成結構圖組成結構圖3. 派生類析構函數派生類析構函數派生類析構函數的形式無特殊之處派生類析構函數的形式無特殊之處 不必顯式地調用各直接基類不必顯式地調用各直接基類 各子對象相應類的析構函數各子對象相應類的析構函數,這些操作是由系統自動完成的這些操作是由系統自動完成的 4. 派生類析構函數的執行順序派生類析構函數的執行順序 直接基類直接基類1數據成員數據成員(除靜態數據成員外除靜態數據成員外)直接

14、基類直接基類2數據成員數據成員(除靜態數據成員外除靜態數據成員外).直接基類直接基類n數據成員數據成員(除靜態數據成員外除靜態數據成員外)子對象子對象1數據成員數據成員(除靜態數據成員外除靜態數據成員外)子對象子對象2數據成員數據成員(除靜態數據成員外除靜態數據成員外).子對象子對象m數據成員數據成員(除靜態數據成員外除靜態數據成員外)派生類本身數據成員派生類本身數據成員(除靜態數據成員外除靜態數據成員外)各直接基類各直接基類 派生類自身數據成員派生類自身數據成員 各子對象各子對象(定義時的順序)(定義時的順序) (定義時的順序)(定義時的順序) #include class Base pub

15、lic: Base()a=0; Base(int i)a=i; void print()couta=a int Geta()return a; Base()coutBase(a=aprivate:int a; ; class Derived:public Base public: Derived()b=0; Derived(int i,int j,int k):Base(i), Derived()coutDerived(b= void print(); 例例 單重繼承派生類析構函數示例單重繼承派生類析構函數示例 程序輸出結果程序輸出結果 :a=0,b=0,Ba.a=0 a=5,b=7,Ba.a

16、=3 Derived(b=7)析構函數析構函數 Base(a=3)析構函數析構函數 Base(a=5)析構函數析構函數 Derived(b=0)析構函數析構函數 Base(a=0)析構函數析構函數 Base(a=0)析構函數析構函數 例例 多重繼承中構造函數和析構函數示多重繼承中構造函數和析構函數示例例 #include class base1 public: base1(int i)i1=i;coutbase1(i base1()coutbase1(i1=iprivate: int i1; ; class base2 public: base2(int i)i2=i;coutbase2(i

17、base2()coutbase2(i2=iprivate: int i2; ; class derived:public base1,public程序輸出結果程序輸出結果 : base1(i1=5)構造函數構造函數 base2(i2=4)構造函數構造函數 base1(i1=2)構造函數構造函數 base2(i2=3)構造函數構造函數 derived構造函數構造函數 derived析構函數析構函數 base2(i2=3)析構函數析構函數 base1(i1=2)析構函數析構函數 base2(i2=4)析構函數析構函數 base1(i1=5)析構函數析構函數 8.4 虛基類虛基類 1. 多級繼承中的

18、二義性問題多級繼承中的二義性問題 多級繼承中的二義性問題多級繼承中的二義性問題 :在多級繼承的情況下在多級繼承的情況下,派生派生類對象可能具有通過類對象可能具有通過不同繼承路徑不同繼承路徑而得到兩個或兩個以上而得到兩個或兩個以上間接基類的間接基類的同名同名成員成員 。 AABC各類的繼承關系圖各類的繼承關系圖D#include class A public: int na; void fun() coutfun() of A(na=; class B:public A public: int nb; ; class C:public A public: int nc; ; class D:pu

19、blic B,public C public: int nd; ; 例例 多級繼承的二義性問題示例多級繼承的二義性問題示例 AABC各類的繼承關系圖各類的繼承關系圖D派生類派生類D對象對象d的組成結構圖的組成結構圖nd ncC A nanbB A na程序輸出結果程序輸出結果 :d.B:A:na=2d.C:A:na=3 fun() of A(na=2) fun() of A(na=3) 2. 虛基類虛基類 通常,不希望結果具有二義性;通常,不希望結果具有二義性; 希望只有一份間接基類的成員被繼承下來希望只有一份間接基類的成員被繼承下來 。 方法:把間接基類轉為虛基類方法:把間接基類轉為虛基類

20、class 派生類名派生類名: virtual 繼承方式繼承方式1 基類名基類名1, virtual 繼承方式繼承方式2 基類名基類名2, 派生類類體派生類類體 ; 派生類類體中未定義的成員函數的實現派生類類體中未定義的成員函數的實現 #include class A public: int na; void fun() coutfun() of A(na=; class B:virtual public A public: int nb; ; class C:virtual public A public: int nc; ; class D:public B,public C public

21、: int nd; ; 例例 采用虛基類避免前例中的二義性采用虛基類避免前例中的二義性AABC各類的繼承關系圖各類的繼承關系圖D派生類派生類D對象對象d的組成結構圖的組成結構圖nd ncC A nanbB 程序輸出結果程序輸出結果 :d.B:A:na=3 d.C:A:na=3 fun() of A(na=3) fun() of A(na=3)3. 虛基類的構造函數和析構函數虛基類的構造函數和析構函數 虛基類的數據成員只被初始化一次虛基類的數據成員只被初始化一次 。 規定:在一個基類初始化表中規定:在一個基類初始化表中 若同時出現對虛基類和非虛基類構造函數的調用,則若同時出現對虛基類和非虛基類構

22、造函數的調用,則虛基類的構造函數優先執行。虛基類的構造函數優先執行。 若同時包括多個虛基類,則按它們在定義派生類時說若同時包括多個虛基類,則按它們在定義派生類時說明的順序調用各虛基類的構造函數。明的順序調用各虛基類的構造函數。#include class A public: A()coutA classn; A()coutclass An; class D1 public: D1()coutD1 classn; D1()coutclass D1n; class D2:public D1,virtual public A public: D2()coutD2 classn; D2()coutcl

23、ass D2n; class D3:public D1,virtual public A 例例 虛基類構造、析構函數調用示例虛基類構造、析構函數調用示例 程序輸出結果程序輸出結果 :A classD1 classD3 classD1 classD2 classD4 classclass D4class D2class D1class D3class D1class AD1AD2D3各類的繼承關系圖各類的繼承關系圖D48.5 賦值兼容規則賦值兼容規則 1. 賦值兼容規則賦值兼容規則 賦值兼容規則:賦值兼容規則:是指在公有繼承的前提下,基類對是指在公有繼承的前提下,基類對象與公有派生類對象之間的象

24、與公有派生類對象之間的自動類型轉換和賦值自動類型轉換和賦值的規的規則。則。 由于派生類中包含從基類繼承的成員,所以可以將由于派生類中包含從基類繼承的成員,所以可以將派生類對象賦值給基類對象,在需要基類對象的任何派生類對象賦值給基類對象,在需要基類對象的任何時候都可以其用派生類對象代替。時候都可以其用派生類對象代替。 公有繼承時公有繼承時 基類對象與派生類對象之間的關系基類對象與派生類對象之間的關系(1)可以用派生類對象給基類對象賦值,反之不行)可以用派生類對象給基類對象賦值,反之不行 。(2)可以用派生類對象初始化基類對象或基類的引用。)可以用派生類對象初始化基類對象或基類的引用。 基類對象的

25、指針與派生類對象的指針之間的關系基類對象的指針與派生類對象的指針之間的關系 (3) 可以把派生類對象的地址賦給指向其基類對象的指針變量。反之不行。可以把派生類對象的地址賦給指向其基類對象的指針變量。反之不行。 (4) 可以把派生類對象的指針賦值給基類對象的指針。反之則錯。可以把派生類對象的指針賦值給基類對象的指針。反之則錯。 2. 賦值兼容規則主要討論兩個問題賦值兼容規則主要討論兩個問題上述上述4條規則只對公有繼承有效。如果對私有繼承條規則只對公有繼承有效。如果對私有繼承或保護繼承使用,則會出現語法錯誤。或保護繼承使用,則會出現語法錯誤。在用基類對象的指針指向派生類對象時,只能直在用基類對象的

26、指針指向派生類對象時,只能直接訪問派生類對象中從基類繼承的公有成員。如果接訪問派生類對象中從基類繼承的公有成員。如果要用基類對象的指針訪問派生類的公有成員,則必要用基類對象的指針訪問派生類的公有成員,則必須進行強制類型轉換須進行強制類型轉換 。 #include class A int x;public: A(int x1)x=x1; void print()coutx=x ;class B:public A int y;public: B(int x1,int y1):A(x1) y=y1; void print() A:print(); cout;void main() B b1(10,2

27、0); b1.print(); A a(b1); /用派生類對象初始化基類對象用派生類對象初始化基類對象a.print(); coutendl;例例 基類、派生類對象之間的關系基類、派生類對象之間的關系 程序輸出結果程序輸出結果 :x=10 y=20 x=10 x=10 y=30 x=10 x=10 y=40 x=10#include class A int x;public: A(int x1)x=x1; void print()coutx=x ;class B:public A int y;public: B(int x1,int y1):A(x1) y=y1; void print()

28、A:print(); couty=yendl; ;void main() 例例 基類對象指針與派生類對象指針之間的關系示例基類對象指針與派生類對象指針之間的關系示例 程序輸出結果程序輸出結果 :x=10 x=3x=3 y=2 例例 有一個機動車類有一個機動車類vehicle,臥車類臥車類car和卡車類和卡車類truck是是vehicle類的派生類類的派生類,每個類有各自相關數據和輸出的內容。每個類有各自相關數據和輸出的內容。 #include class vehicle /定義機動車類定義機動車類 vehicle public: vehicle(int w,double r); void show(); protected: int wheels; /車輪個數車輪個數 double range; /行程公里數行程公里數 ; class car:public vehicle /定義臥車類定義臥車類car程序輸出結果程序輸出結果 :小車小車:車輪車輪=4個個 行程行程=1000

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論