版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、 如果一個派生類只從一個基類派生,稱為單繼承; 如果一個派生類從多個基類派生,稱為多重繼承 關于繼承的幾點說明: 如果子類繼承了父類,則子類自動具有父類的全部數據成員(數據結構)和成員函數(功能);但是,子類對父類成員的訪問有所限制。 子類可以定義自己的成員是數據成員和成員函數。 基類、派生類或父類、子類都是“相對”的。一個類派生出新的類就是基類。派生類也可以被其他類繼承,這個派生類同時也是基類。第1頁/共46頁派生類的定義 語法格式如下: class 派生類名 : 繼承方式 基類名 新增私有成員聲明語句列表public: 新增公有成員聲明語句列表protected: 新增保護成員聲明語句列表
2、;例如:class Book/定義基類Book private:int num;/書號float price;/定價int sellnum;/銷售量 public:float sale()/計算銷售額 return price*sellnum; ;class Book1:public Book /定義派生類Book1 private:char type;/定義圖書類別,新增加的數據成員char name40; /書名,新增加的數據成員char publisher20; /出版社,新增加的數據成員 public:void show()/顯示圖書信息,新增加的成員函數 couttype:typee
3、ndl;coutname:nameendl;coutpublisher:publisherendl;第2頁/共46頁派生類的構成 派生類中的成員包括兩部分,一部分是從基類繼承過來的成員,一部分是在聲明派生類時新增加的成員,每一部分均包括數據成員和成員函數。 派生類要繼承基類的所有成員,對基類的繼承方式不同,其訪問屬性也不同 派生類可以在原有基類成員的基礎上添加新的成員,也可以更改原有成員屬性。若在派生類中聲明一個與基類成員同名的新成員,該成員就會覆蓋原有的成員;若聲明的是同名函數,要保證函數的參數也完全相同第3頁/共46頁【回顧】類中的成員的不同訪問權限 public公有成員: 一個類的公有成
4、員允許本類的成員函數、本類的對象、公有派生類的成員函數、公有派生類的對象訪問。 private私有成員: 一個類的私有成員只允許本類的成員函數訪問。 protected保護成員: 具有私有成員和公有成員的特性,對其派生類而言是公有成員,對其他而言是私有成員?;悢祿蓡T聲明為保護的是有益的,派生類可以自由訪問,外部不能訪問,既實現了信息重用,又做到了信息隱藏。第4頁/共46頁【例7.2】類的各種成員的訪問權限。#includeclass A int i;/私有成員protected: /保護成員int j;void fn1() cout保護成員i=i j=jendl;public: /公有成員
5、A(int x,int y) i=x;j=y;void fn2()/成員函數可以訪問保護成員 cout公有成員i=i j=jendl;fn1();void main() A x(21,63);x.fn2();執(zhí)行結果: 公有成員i=21 j=63保護成員i=21 j=63在主程序中只能訪問公有成員,成員函數可以訪問保護成員和私有成員,在例7.2中,只能由函數fn2()訪問函數fn1(),不能在主程序中調用x.fn1()。第5頁/共46頁派生類的繼承方式 繼承方式決定了子類對父類的訪問權限,有3種繼承方式: private、public和protected,默認為private1公有繼承【例79
6、-1】 當派生類的繼承方式是公有繼承(public)時,基類的public成員和protected成員的訪問屬性在派生類中保持不變,基類的private成員被繼承到派生類中仍是基類的private成員。第6頁/共46頁2私有繼承【例79-2】當派生類的繼承方式是私有繼承(private)時,基類的public成員和protected成員被繼承到派生類中成為private成員,基類的private成員被繼承到派生類中仍為private成員第7頁/共46頁【例7.3】學校職工類的公有繼承和私有繼承。類people是基類,定義人的姓名、性別、身份號和對這3種數據的顯示。類member私有繼承peop
7、le,定義了職工號、部門和信息顯示,類member生成的對象不能直接訪問類people中的任何成員。類worker公有繼承類member,定義了崗位和信息顯示,類worker生成的對象可以直接訪問類member中的公有成員。類teacher私有繼承類member,定義了執(zhí)教課程和信息顯示,類teacher生成的對象不能直接訪問類member中的任何成員。第8頁/共46頁#include#includeclass peoplechar name10,sex;/姓名,性別long idnumber;/身份號碼public:people(long num=0,char* n= ,char s=m)
8、/構造函數 idnumber=num;strcpy(name,n);sex=s; void p_show() cout人員:身份號=idnumber;cout姓名=name性別=sexendl; ;第9頁/共46頁class member:private people /教工類私有繼承people類int m_num;/工號public:char department10;/部門member(long n,char* na,char s=m,int mn=0,char* md=0):people(n,na,s) m_num=mn; strcpy(department,md); /構造函數voi
9、d m_show()cout教工t;p_show();/訪問基類的公有成員cout教工編號:m_num=m_num單位=departmentendl;第10頁/共46頁class worker:public member/工人類公有繼承類memberchar station10;/崗位public:worker(long n,char* na,char s=m,int mn=0,char* md=0,char* st=0):member(n,na,s,mn,md) strcpy(station,st); /構造函數void w_show()cout工人t;m_show();/訪問基類的公有成員
10、cout崗位=stationendlendl; ;第11頁/共46頁class teacher:private member/教師類私有繼承基類memberchar course10;/執(zhí)教課程public:teacher(long n,char* na,char s=m,int mn=0,char* md=0,char* tc=0):member(n,na,s,mn,md) strcpy(course,tc); /構造函數void t_show()cout教師t;m_show();/訪問基類的公有成員cout課程=courseendlendl; ;第12頁/共46頁void main() w
11、orker w(123456,王祥,m,3761,生物系,實驗室);w.w_show();w.m_show();/worker類公有繼承member,所以可以直接訪問member類的公有成員/w.p_show(); member類私有繼承people,不可以直接訪問people類的公有成員teacher t(661001,李輝,m,1954,計算機系,C+);t.t_show();/t.m_show(); teacher類私有繼承member,不可以直接訪問member類的公有成員/t.p_show(); teacher類私有繼承member,member私有繼承people類,不可以直接訪問
12、people類的公有成員執(zhí)行結果為: 工人教工人員: 編號=123456姓名=王祥性別=m教工編號: m_num=3761 單位=生物系崗位=實驗室教工人員: 編號=123456姓名=王祥性別=m教工編號: m_num=3761單位=生物系教師教工人員: 編號=661001姓名=李輝性別=m教工編號: m_num=1954 單位=計算機系課程=C+第13頁/共46頁3保護繼承【例79-3】 當派生類的繼承方式是保護繼承(protected)時,基類的public成員和protected成員被繼承到派生類中成為派生類的protected成員,基類的private成員被繼承到派生類中仍為priva
13、te成員。第14頁/共46頁【例7.4】類的保護繼承。#includeclass Aint i;protected:int j;void show_A1() coutA保護顯示: i=i j=jendl; public:A(int x,int y) i=x; j=y; void show_A2()coutA2在執(zhí)行show_A1().;show_A1();coutA2執(zhí)行完畢。endl; ;class B:protected Aint x;public:B(int i,int j,int k):A(i,j) x=k; void show_B()coutB在執(zhí)行show_A1().;show_A
14、1();/保護繼承可以訪問A的保護成員coutB公有顯示:x=xendl; coutB執(zhí)行完畢。endl;第15頁/共46頁class C:public Bpublic:C(int i,int j,int x):B(i,j,x) /空語句void show_C()coutC在執(zhí)行show_A2().;show_A2();/說明可以訪問A2,A2是B的保護成員coutC在執(zhí)行show_A1().;/這兩句是多余的。show_A1();/說明可以訪問A1,A1也是B的保護成員coutC在執(zhí)行show_B().;show_B();coutC執(zhí)行完畢。endl;void main() B b(1,2,
15、3);b.show_B();/b.show_A2(); B從A類保護繼承,所以不能直接訪問A類的公有成員C c(100,200,300); c.show_C();/c.show_A2(); C從B類公有繼承,而B從A保護繼承,所以不能直接訪問A類的公有成員第16頁/共46頁執(zhí)行結果為: B在執(zhí)行show_A1().A保護顯示: i=1 j=2B公有顯示: x=3B執(zhí)行完畢。C在執(zhí)行show_A2().A2在執(zhí)行show_A1().A保護顯示: i=100 j=200A2執(zhí)行完畢。C在執(zhí)行show_A1().A保護顯示: i=100 j=200C在執(zhí)行show_B().B在執(zhí)行show_A1()
16、.A保護顯示: i=100 j=200B公有顯示: x=300B執(zhí)行完畢。C執(zhí)行完畢。ijxShow_A1()Show_A2()Show_B()在A 中私有保護無保護公有無在B中不可見保護私有保護保護公有在C中不可見保護不可見保護保護公有第17頁/共46頁繼承方式與成員的訪問屬性第18頁/共46頁派生類的構造函數和析構函數 在派生關系中,構造函數和析構函數是不能繼承的,對派生類要重新定義構造函數和析構函數1、派生類構造函數的定義格式:派生類名(總參數列表): 基類名(參數列表1),子對象名1(參數列表2),子對象名2(參數列表3), 派生類中新增數據成員的初始化語句 注意:1)派生類構造函數可
17、在類中聲明,類外定義,聲明時不給出基類構造函數名及其參數列表;2)派生類構造函數定義時,其參數列表既有參數類型也有參數名稱,而其后的基類的參數列表只有參數名稱;第19頁/共46頁 執(zhí)行構造函數的順序是:派生類構造函數先調用基類的構造函數,對基類數據成員初始化,再執(zhí)行派生類構造函數本身,對派生類數據成員初始化。 包含子對象的派生類構造函數的執(zhí)行順序是:派生類構造函數先調用基類的構造函數,對基類數據成員初始化;再調用子對象構造函數,對子對象數據成員初始化,最后執(zhí)行派生類構造函數本身,對派生類數據成員初始化。2派生類的析構函數 派生類析構函數沒有函數類型、沒有參數,其定義及使用方法與一般類的析構函數
18、相同。派生類的析構函數用來對派生類中所增加的成員進行清理工作,同時系統(tǒng)會自動調用基類的析構函數和子對象的析構函數,對基類和子對象進行清理。 析構函數的調用順序與構造函數正好相反:先執(zhí)行派生類的析構函數,然后調用子對象的析構函數,最后調用基類的析構函數,對基類進行清理?!纠?9-4】【例79-5】第20頁/共46頁【例7.1】圓Circle類繼承點Point類。class Point float x,y;public: Point(float a=0,float b=0)x=a;y=b;void SetP(float a=0,float b=0)x=a;y=b;void Display() co
19、ut位置是: (x,y)n;class Circle: public Pointfloat r;public: Circle(float z=1,float x=0,float y=0):point(x,y)r=z;void SetC(float z=1,float x=0,float y=0)r=z;SetP(x,y);void Print()cout圓的;Display();cout圓的半徑是: rendl;第21頁/共46頁void main()Circle a(3.2);a.Print();a.SetC(6,8,2);a.Print();運行結果為: 圓的位置是: (0,0) 圓的半徑
20、是: 3.2圓的位置是: (8,2)圓的半徑是: 6第22頁/共46頁【例7.5】聲明一個派生類對象的實際操作步驟。 設計基類。如要建立教工類,首先建立人員基類。class peoplechar name10,sex;/姓名,性別long idnumber;/身份號碼public: people(long num=0,char* n=,char s=m) /構造函數idnumber=num;strcpy(name,n);sex=s;void p_show()cout人員: 身份號=idnumber;cout姓名=name性別=sexendl;第23頁/共46頁 設計派生類。class memb
21、er: public people/教工類公有繼承people類int m_num;/工號public: char department10;/部門member(long n,char* na,char s=m,int mn=0,char* md=0): people(n,na,s) m_num=mn;strcpy(department,md);/構造函數void m_show()cout教工t;p_show();/訪問基類的公有成員cout教工編號: m_num=m_num單位=departmentendl; 定義對象。聲明派生類member類對象。member w(123456,王一,m,
22、789,計算機系);創(chuàng)建該類對象時,自動調用member類的構造函數,再由member類的構造函數調用基類people類的構造函數。首先執(zhí)行的是基類 people類的構造函數,創(chuàng)建它的成員,然后執(zhí)行派生類member類的構造函數,從而創(chuàng)建它的成員。第24頁/共46頁【例7.6】設計表示學校教師、職工和學生的類及其繼承關系。#include#includeclass peoplechar name10,sex;/姓名,性別long idnumber;/身份號碼public:people(long num=0,char* n= ,char s=m) /構造函數 idnumber=num;strcp
23、y(name,n);sex=s; void p_show() cout人員:身份號=idnumber;cout姓名=name性別=;if (sex=m|sex=M) cout男endl; if (sex=w|sex=W) cout女endl; ;第25頁/共46頁class student:public people/學生類公有繼承people類int s_num;/學號public:int s_class;/班級student(long n,char* na,char s=m,int sn=0,int sc=0):people(n,na,s) s_num=sn;s_class=sc; /構造
24、函數void s_show()cout學生t;p_show();cout學號=s_num班級=s_classendl; ;class member:public people /教工類公有繼承people類int m_num;/工號public:char department10;/部門member(long n,char* na,char s=m,int mn=0,char* md=0):people(n,na,s) m_num=mn; strcpy(department,md); /構造函數void m_show()cout教工t;p_show();/訪問基類的公有成員cout教工編號=m
25、_num單位=department;第26頁/共46頁class worker:public member/工人類公有繼承類memberchar station10;/崗位public:worker(long n,char* na,char s=m,int mn=0,char* md=0,char* st=0):member(n,na,s,mn,md) strcpy(station,st); /構造函數void w_show()cout工人t;m_show();/訪問基類的公有成員coutt崗位=stationendl; ;class teacher:public member/教師類公有繼承
26、基類memberchar course10;/執(zhí)教課程public:teacher(long n,char* na,char s=m,int mn=0,char* md=0,char* tc=0): member(n,na,s,mn,md) strcpy(course,tc); /構造函數void t_show()cout教師t;m_show();/訪問基類的公有成員coutt執(zhí)教課程=courseendl; ;第27頁/共46頁void main() people p(981102,趙一,w);p.p_show();student s(781010,錢二,m,1001,982);s.s_sh
27、ow();worker w(123456,孫三,m,123,計算機系,秘書);w.w_show();teacher t(661001,李四,m,456,計算機系,C+);t.t_show();cout直接訪問公有基類的公有成員:endl;t.m_show();/公有繼承的派生類對象直接訪問基類的公有成員t.p_show();/公有繼承的派生類對象直接訪問基類的基類的公有成員coutt.departmentendl;/直接訪問基類的公有數據成員 第28頁/共46頁執(zhí)行結果為: 人員: 身份號=981102姓名=趙一性別=女學生人員: 身份號=781010姓名=錢二性別=男學號=1001班級=98
28、2工人教工人員: 身份號=123456姓名=孫三性別=男教工編號=123單位=計算機系崗位=秘書教師教工人員: 身份號=661001姓名=李四性別=男教工編號=456單位=計算機系執(zhí)教課程=C+直接訪問公有基類的公有成員: 教工人員: 身份號=661001姓名=李四性別=男教工編號=456單位=計算機系人員: 身份號=661001姓名=李四性別=男計算機系第29頁/共46頁多重繼承 多重繼承的聲明class 派生類名 :繼承方式1 基類名1,繼承方式2 基類名2, 派生類新增加的成員;; 例如:class D:public A,private B,protected C ;第30頁/共46頁多
29、重繼承派生類的構造函數 派生類名(總參數列表): 基類名1(參數列表),基類名2(參數列表), ,子對象名1(參數列表),子對象名2(參數列表), 派生類新增成員初始化語句;; 多重繼承構造函數的執(zhí)行順序與單繼承相同,即先調用所有基類的構造函數,再調用子對象的構造函數,最后執(zhí)行派生類構造函數。 【例79-6】第31頁/共46頁【例7.7】一個簡單的多繼承。#includeclass Aint i;public: A(int ii=0)i=ii;void show() coutA show()A中i=iendl;class Bint i;public: B(int ii=0) i=ii;void
30、 show() coutB show()B中i=iendl;class C: public A,public Bint i;public: C(int iA=0,int iB=0,int iC=0): A(iA),B(iB)i=iC;void show()coutC show()C中i=iendl;void main()C c(1,2,3);c.A show();/調用對象c的基類A的成員函數show()c.B show();/調用對象c的基類B的成員函數show()c.show();/調用對象c所屬的類C的成員函數show()執(zhí)行結果為: A show()A中i=1B show()B中i=2
31、C show()C中i=3第32頁/共46頁【例7.8】西紅柿的多繼承。定義水果和蔬菜2個類作為基類,西紅柿作為派生類。class fruit/定義水果類public: print() cout直接食用,味道鮮美!endl;class vegetable/定義蔬菜類public: print() cout燒炒烹炸,餐桌佳肴!endl;class tomato: public fruit,public vegetable/定義西紅柿類public: print() cout西紅柿: 酸甜可口!endl;void main()tomato t;t.print();t.fruit print();/
32、訪問fruit基類的成員函數t.vegetable print();/訪問vegetable基類的成員函數運行結果為: 西紅柿: 酸甜可口!直接食用,味道鮮美!燒炒烹炸,餐桌佳肴!第33頁/共46頁二義性問題 當一個派生類繼承的多個基類中有同名成員時,可能出現對基類中某成員的訪問不唯一的情況,這就是對基類成員訪問的二義性問題。 解決二義性問題的方法:1、在引用同名成員時,通過在成員名前加上類名和作用域運算符“:”可以區(qū)別來自不同基類的成員。2、如果派生類中定義了與基類同名的成員,則派生類新增加的同名成員將覆蓋基類中的同名成員。 【例79-7】第34頁/共46頁虛基類 當一個派生類有多個直接基類
33、,而這些直接基類又有一個共同的基類,則派生類中會保留這個共同基類成員的多份同名成員。 C+引入了虛基類方法,使得派生類在繼承間接共同基類時只保留一份同名成員。第35頁/共46頁虛基類的聲明 虛基類的聲明class 派生類名 :virtual 繼承方式 基類名例如:class A public:void display(); protected:int a;class B:virtual public A protected:int b;class C:virtual public A protected: int c;class D:public B,public C public: void
34、 display_d(); private: int d;第36頁/共46頁虛基類的構造函數 虛基類的初始化與一般的多重繼承的初始化在語法上一致,但構造函數的執(zhí)行次序不同:通常先執(zhí)行虛基類的構造函數,再執(zhí)行非虛基類的構造函數;當包含多個虛基類時,需按它們說明的順序執(zhí)行。 【例79-8】第37頁/共46頁【例7.9】 一個虛基類繼承的例子。#includeclass Apublic: void fn()coutA: fn()endl;class B1: virtual public A/虛擬繼承public: void fn()coutB1: fn()endl;class B2: virtual
35、 public A/虛擬繼承public: void fn()coutB2: fn()endl;class C1: public B1 ;class C2: public B2 ;class D: public C1,public C2 ;void main()D obj;obj.C1 fn();obj.C2 fn();obj.A fn();/可以執(zhí)行,無二義性執(zhí)行結果為: B1: fn1()B2: fn1()A: fn()若類A不是虛基類,則語句obj.A fn()就不能執(zhí)行,這是因為計算機無法確定是執(zhí)行B1繼承的基類A的函數,還是執(zhí)行B2繼承的基類A的函數,具有二義性第38頁/共46頁【例
36、7.10】虛基類的構造函數。#include #include class basechar name15;public: base(char* m=王五)strcpy(name,m);void show() coutbase輸出: nameendl;class base1: virtual public basepublic: base1(char* m): base(m);class base2: virtual public basepublic: base2(char*m): base(m);第39頁/共46頁class derive: virtual public base1,pub
37、lic base2char name15;public: derive(char*,char*,char*,char*);derive(char*,char*,char*);void showD() coutderive輸出: nameendl;derive derive(char* p,char* q,char* r,char *t): base(p),base1(q),base2(r) strcpy(name,t);derive derive(char* p,char* q,char* r): base1(p),base2(q) strcpy(name,r);void main()deri
38、ve d(趙易,錢耳,孫傘,李思);d.show();d.showD();derive c(趙易,錢耳,孫傘);c.show();c.showD();base1 b(周武);b.show();輸出結果為: base輸出: 趙易derive輸出: 李思base輸出: 王五derive輸出: 孫傘base輸出: 周武第40頁/共46頁【例7.11】設計一個表示在職學生的類。先設計一個基類people,表示一般人員的基本信息,再設計一個表示工作人員的類job,還要設計一個表示學生的類student,以這些類作為基類派生出在職學生類。#include#includeclass peoplechar n
39、ame10,sex;/姓名,性別long idnumber;/身份號碼public: people(long num=0,char* n=,char s=m) /構造函數idnumber=num;strcpy(name,n);sex=s;void p_show()cout人員: 身份號=idnumber;cout姓名=name性別=;if (sex=m|sex=M) cout男endl;if (sex=w|sex=W) cout女endl;第41頁/共46頁class job: virtual public people/工作人員類公有繼承people虛基類int m_num;/工號char department10;/單位public: job(long n,char* na,char s=m,int m
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度電商虛擬現實技術應用委托經營協(xié)議3篇
- 二零二五年度奶粉品牌線上直播帶貨代理合同
- 二零二五版智能停車場建設工程承包簡易合同3篇
- 二零二五年度公益活動布展策劃與實施協(xié)議3篇
- 2025年度煤炭行業(yè)信用風險管理合作協(xié)議書
- 2025年綠色建筑項目泥水工安全責任合同
- 二零二五年度馬鈴薯種植保險及風險防控合作協(xié)議4篇
- 二零二五年船舶空調系統(tǒng)改造與環(huán)保驗收合同3篇
- 個人住宅室內裝修設計服務合同(2024版)3篇
- 2025年度化肥電商平臺合作與服務協(xié)議2篇
- 物流無人機垂直起降場選址與建設規(guī)范
- 肺炎臨床路徑
- 外科手術鋪巾順序
- 創(chuàng)新者的窘境讀書課件
- 綜合素質提升培訓全面提升個人綜合素質
- 如何克服高中生的社交恐懼癥
- 聚焦任務的學習設計作業(yè)改革新視角
- 移動商務內容運營(吳洪貴)任務三 APP的品牌建立與價值提供
- 電子競技范文10篇
- 食堂服務質量控制方案與保障措施
- VI設計輔助圖形設計(2022版)
評論
0/150
提交評論