[文学]7继承与派生shulippt课件_第1页
[文学]7继承与派生shulippt课件_第2页
[文学]7继承与派生shulippt课件_第3页
[文学]7继承与派生shulippt课件_第4页
[文学]7继承与派生shulippt课件_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+语言程序设计类的继承与派生重点类成员的访问控制重点单继承与多继承派生类的构造、析构函数重点类成员的标识与访问保持已有类的特性而构造新类的过程称为继承。在已有类的根底上新增自己的特性而产生新类的过程称为派生。被继承的已有类称为基类或父类。派生出的新类称为派生类。工具车轿车面包车小汽车卡车旅行车汽车汽车交通工具交通工具类的继承与派生7.1猴子猴子狮子虎猎豹猫猫鸟鸟动物动物类的继承与派生7.1圆圆矩形矩形几何形状几何形状类的继承与派生7.1兼职技术人员销售经理管理人员销售人员雇员类的继承与派生7.1继承的目的:实现代码重用。派生的目的:当新的问题出现,原有程序无法解决或不能完全解决时,需要对原有

2、程序进展改造。类的继承与派生7.1class 派生类名:继承方式 基类名 成员声明;;类的继承与派生7.110class C:public A,private Bpublic: C; C;class D:public C public: D; D;11吸收基类成员 除构造函数和析构函数外,全盘吸收改造基类成员 基类成员访问控制 对基类数据成员和函数成员隐藏添加基类成员 保证功能上有所开展12class employeeprotected:char name20; /姓名姓名int individualEmpNo;/个人编号个人编号int grade;/级别级别float accumPay; /

3、月薪总额月薪总额static int employeeNo;/本公司职员编号目前最大值本公司职员编号目前最大值public:employee;/构造函数构造函数employee; /析构函数析构函数void pay;/计算月薪函数计算月薪函数void promoteint;/晋级函数晋级函数void SetNamechar *; /设置姓名函数设置姓名函数char * GetName; /提取姓名函数提取姓名函数int GetindividualEmpNo; /提取编号函数提取编号函数int Getgrade; /提取级别函数提取级别函数float GetaccumPay; /提取月薪函数提取

4、月薪函数;13class technician:public employee/兼职技术人员类兼职技术人员类private:float hourlyRate; /每小时酬金每小时酬金int workHours;/当月工作时数当月工作时数 / 添加新数据成员添加新数据成员public:technician;/构造函数构造函数void SetworkHoursint wh; /设置工作时设置工作时数数 / 添加新成员函数添加新成员函数void pay;/计算月薪函数计算月薪函数同名隐藏同名隐藏;不同继承方式的影响主要表达在:派生类派生类成员成员对基类成员的访问权限对基类成员的访问权限通过派生类通过

5、派生类对象对象对基类成员的访问权限对基类成员的访问权限三种继承方式公有继承公有继承私有继承私有继承保护继承保护继承类成员的访问控制7.2基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象只能访问基类的public成员。类成员的访问控制7.2class Point/基类Point类的声明public:/公有函数成员void InitPfloat xx=0, float yy=0 X=xx;Y=yy;voi

6、d Movefloat xOff, float yOff X+=xOff;Y+=yOff;float GetX return X;float GetY return Y; private:/私有数据成员float X,Y;类成员的访问控制7.2class Rectangle: public Point /派生类声明public:/新增公有函数成员void InitRfloat x, float y, float w, float hInitPx,y;W=w;H=h;/调用基类公有成员函数float GetH return H;float GetW return W;private:/新增私有数

7、据成员float W,H;17#include#includeusing namecpace std;int main Rectangle rect;rect.InitR2,3,20,10; /通过派生类对象访问基类公有成员rect.Move3,2; coutrect.GetX, rect.GetY,rect.GetH,rect.GetWendl;return 0;18基类的public和protected成员都以private身份出如今派生类中,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的privat

8、e成员。通过派生类的对象不能直接访问基类中的任何成员。类成员的访问控制7.2/rectangle.hclass Point /基类Point类的声明public:/公有函数成员void InitPfloat xx=0, float yy=0 X=xx;Y=yy;void Movefloat xOff, float yOff X+=xOff;Y+=yOff;float GetX return X;float GetY return Y;private:/私有数据成员float X,Y;类成员的访问控制7.221class Rectangle: private Point/派生类声明public:

9、/新增外部接口void InitRfloat x, float y, float w, float hInitPx,y;W=w;H=h;/访问基类公有成员void Movefloat xOff, float yOff Point:MovexOff,yOff;float GetX return Point:GetX;float GetY return Point:GetY;float GetH return H;float GetW return W;private:/新增私有数据float W,H;类成员的访问控制7.2#include#includeusing namecpace std;i

10、nt main /通过派生类对象只能访问本类成员 Rectangle rect;rect.InitR2,3,20,10;rect.Move3,2;coutrect.GetX, rect.GetY,rect.GetH,rect.GetWendl;return 0;22基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可直接访问。派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。通过派生类的对象不能直接访问基类中的任何成员类成员的访问控制7.2对建立其所在类对象的模块来说

11、,它与 private 成员的访问性质一样,不可访问。对于其派生类来说,它与 public 成员的访问特性一样。 保护成员可以被它的派生类访问,不能被其它外部使用者访问既实现了数据隐藏,又方便继承,实现代码重用。类成员的访问控制7.2class A protected: int x;int main A a; a.x=5;类成员的访问控制7.2/*错误错误, protected成员的访问规那么和成员的访问规那么和私有成员一样私有成员一样*/class A protected: int x;class B: public A public: void Function;void B:Functi

12、on x=5; 26/正确正确一个公有派生类的对象在使用上可以被当作基类的对象,反之那么制止。详细表如今:派生类的对象可以被赋值给基类对象。派生类的对象可以被赋值给基类对象。派生类的对象可以初始化基类的引用。派生类的对象可以初始化基类的引用。指向基类的指针也可以指向派生类。指向基类的指针也可以指向派生类。通过基类对象名、指针只能使用从基类继承的成员类型兼容:理解7.328class B.;class D:public B.;B b1,*pb1;D d1;派生类的对象可以被赋值给基类对象。派生类的对象可以被赋值给基类对象。 b1=d1派生类的对象可以初始化基类的引用。派生类的对象可以初始化基类的

13、引用。 B &bb=d1指向基类的指针也可以指向派生类。指向基类的指针也可以指向派生类。 pb1=&d1#include using namecpace std;class B0/基类B0声明 public:void display coutB0:displayendl; /公有成员函数;类型兼容:理解7.3class B1: public B0 public:void displaycoutB1:displayendl;class D1: public B1public:void displaycoutD1:displaydisplay; /对象指针-成员名 30void m

14、ain /主函数 B0 b0; /声明B0类对象B1 b1; /声明B1类对象D1 d1; /声明D1类对象B0 *p;/声明B0类指针p=&b0; /B0类指针指向B0类对象funp;p=&b1; /B0类指针指向B1类对象funp;p=&d1; /B0类指针指向D1类对象funp;运行结果:B0:displayB0:displayB0:display31单继承派生类只从一个基类派生。派生类只从一个基类派生。多继承派生类从多个基类派生。派生类从多个基类派生。多重派生由一个基类派生出多个不同的派生类。由一个基类派生出多个不同的派生类。多层派生派生类又作为基类,继续派生新

15、的类。派生类又作为基类,继续派生新的类。单继承与多继承7.4class 派生类名:继承方式1 基类名1,继承方式2 基类名2,. 成员声明;注意:每一个“继承方式,只用于限制对紧随其后之基类的继承。单继承与多继承7.4class A public: void setAint; void showA; private: int a;class B public: void setBint; void showB;private: int b;class C : public A, private B public: void setCint, int, int; void showC; priv

16、ate: int c;单继承与多继承7.4void A:setAint x a=x; void B:setBint x b=x; void C:setCint x, int y, int z /派生类成员直接访问基类的 /公有成员 setAx; setBy; c=z;/其它函数实现略int main C obj; obj.setA5; obj.showA; obj.setC6,7,9; obj.showC;/ obj.setB6; 错误/ obj.showB; 错误 return 0;35基类的构造函数不被继承,派生类中需要声明自己的构造函数。声明构造函数时,只需要对本类中新增成员进展初始化,

17、对继承来的基类成员的初始化,自动调用基类构造函数完成。派生类的构造函数需要给基类的构造函数传递参数派生类的构造、析构函数7.5派生类名:派生类名基类所需的形参,本类成员所需的形参:基类名参数表 本类成员初始化赋值语句;派生类的构造、析构函数7.5#includeusing namecpace std;class B public: B; Bint i; B; void Print const; /常成员函数 private: int b;派生类的构造、析构函数7.5B:B b=0;coutBs default constructor called.endl;B:Bint i b=i; cout

18、Bs constructor called. endl;B:B coutBs destructor called.endl; void B:Print const coutbendl; 39class C:public B public: C; Cint i,int j; C; void Print const;private: int c;40C:C c=0;coutCs default constructor called.endl;C:C int i,int j:Bi c=j;coutCs constructor called.endl;C:C coutCs destructor cal

19、led.endl; void C:Print const B:Print; coutcendl; void main C obj5,6;obj.Print; 41派生类名:派生类名基类1形参,基类2形参,.基类n形参,本类形参:基类名1参数, 基类名2参数, .基类名n参数 本类成员初始化赋值语句;派生类的构造、析构函数7.5当基类中声明有默认形式的构造函数或未声明构造函数时,派生类构造函数可以不向基类构造函数传递参数。假设基类中未声明构造函数,派生类中也可以不声明,全采用缺省形式构造函数。当基类声明有带形参的构造函数时,派生类也应声明带形参的构造函数,并将参数传递给基类构造函数。派生类的构造

20、、析构函数7.5派生类名:派生类名基类1形参,基类2形参,.基类n形参,本类形参,内嵌对象形参:基类名1参数, 基类名2参数, .基类名n参数,对象数据成员的初始化 本类成员初始化赋值语句;派生类的构造、析构函数7.51 调用基类构造函数,调用顺序按照它们被继承时声明的顺序从左向 右。2 调用成员对象的构造函数,调用顺序按照它们在类中声明的顺序。3 派生类的构造函数体中的内容。派生类的构造、析构函数7.5#include using namecpace std;class B1/基类B1,构造函数有参数public:B1int i coutconstructing B1 iendl;class

21、 B2/基类B2,构造函数有参数public:B2int j coutconstructing B2 jendl;class B3/基类B3,构造函数无参数public:B3coutconstructing B3 *endl;派生类的构造、析构函数7.5class C: public B2, public B1, public B3 public:/派生类的公有成员Cint a, int b, int c, int d: B1a,memberB2d,memberB1c,B2b private:/派生类的私有对象成员B1 memberB1;B2 memberB2;B3 memberB3;void

22、 main C obj1,2,3,4; 运行结果:constructing B2 2constructing B1 1constructing B3 *constructing B1 3constructing B2 4constructing B3 *47假设建立派生类对象时调用缺省拷贝构造函数,那么编译器将自动调用基类的缺省拷贝构造函数。假设编写派生类的拷贝构造函数,那么需要为基类相应的拷贝构造函数传递参数。例如:C:CC &c1:Bc1 *类型兼容规那么起了作用:可以用派类型兼容规那么起了作用:可以用派生类的引用初始化基类的引用。生类的引用初始化基类的引用。派生类的构造、析构函数

23、7.5析构函数也不被继承,派生类自行声明声明方法与一般无继承关系时类的析构函数一样。不需要显式地调用基类的析构函数,系统会自动隐式调用。析构函数的调用次序与构造函数相反。派生类的构造、析构函数7.5#include using namecpace std;class B1/基类B1声明 public:B1int i coutconstructing B1 iendl;B1 coutdestructing B1 endl;class B2/基类B2声明public:B2int j coutconstructing B2 jendl;B2 coutdestructing B2 endl;class

24、 B3/基类B3声明public:B3coutconstructing B3 *endl;B3 coutdestructing B3 endl;派生类的构造、析构函数7.5class C: public B2, public B1, public B3public:Cint a, int b, int c, int d: B1a,memberB2d,memberB1c,B2bprivate:B1 memberB1;B2 memberB2;B3 memberB3;void main C obj1,2,3,4; 51constructing B2 2constructing B1 1constru

25、cting B3 *constructing B1 3constructing B2 4constructing B3 *destructing B3destructing B2destructing B1destructing B3destructing B1destructing B2当派生类与基类中有一样成员时:假设未强行指明,那么通过派生类对象使用的是派生类中的同名成员。即使函数参数不同也要重载。 派生类对象.数据成员名; 派生类对象.函数成员名参数表;如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定。 使用作用域分辨符: 派生类对象. 基类名:数据成员名; 派生类对象.

26、 基类名:函数成员名参数表;派生类成员的标识与访问7.6#include using namecpace std;class B1/声明基类B1 public:/外部接口int nV;void fun coutMember of B1endl;class B2/声明基类B2 public:/外部接口int nV;void funcoutMember of B2endl;class D1: public B1, public B2 public:int nV;/同名数据成员void funcoutMember of D1endl;/同名函数成员;派生类成员的标识与访问7.6void main D

27、1 d1;d1.nV=1; /对象名.成员名标识, 访问D1类成员d1.fun; d1.B1:nV=2;/作用域分辨符标识, 访问基类B1成员d1.B1:fun;d1.B2:nV=3;/作用域分辨符标识, 访问基类B2成员d1.B2:fun;55运行结果:Member of D1Member of B1Member of B2在多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性不确定性采用虚函数第8章或同名隐藏规那么来解决。当派生类从多个基类派生,而这些基类又从同一个基类派生,那么在访问此共同基类中的成员时,将产生二义性采用虚基类来解决。派生类成员的标识与访问7.6cl

28、ass A public: void f;class B public: void f; void g;class C: public A, public B public: void g; void h;假如声明:C c1;那么 c1.f; 具有二义性而 c1.g; 无二义性同名覆盖派生类成员的标识与访问7.6解决方法一:用类名来限定c1.A:f 或 c1.B:f解决方法二:同名覆盖在C 中声明一个同名成员函数f, 在f中再根据需要调用 A:f 或 B:f派生类成员的标识与访问7.6class B public: int b;class B1 : public B private: int

29、b1;class B2 : public B private: int b2;class C : public B1,public B2 public: int f; private: int d;派生类成员的标识与访问7.6派生类C的对象的存储构造示意图:bb1bb2dB类成员B类成员B1类成员B2类成员C类对象有二义性:有二义性:C c;c.bc.B:b无二义性:无二义性:c.B1:bc.B2:b60使用作用域标识符使用作用域标识符来唯一标识,必须来唯一标识,必须用直接基类来限定用直接基类来限定虚基类的引入用于有共同基类的场合用于有共同基类的场合声明以以virtual修饰说明基类修饰说明基

30、类例:例:class B1:virtual public B作用主要用来解决多继承时可能发生的对同一基类主要用来解决多继承时可能发生的对同一基类继承屡次而产生的二义性问题继承屡次而产生的二义性问题.为最远的派生类提供唯一的基类成员,而不重为最远的派生类提供唯一的基类成员,而不重复产生屡次拷贝复产生屡次拷贝注意:在在第一级第一级继承时就要将共同基类设计为虚基类。继承时就要将共同基类设计为虚基类。class B private: int b;class B1 : virtual public B private: int b1;class B2 : virtual public B private

31、: int b2;class C : public B1, public B2 private: float d;下面的访问是正确的:C cobj;cobj.b; 虚 基 类7.7虚基类的派生类对象存储构造示意图:BB1B2Cb1b2dB1类成员类成员B2类成员类成员C类对象类对象bB类成员类成员63 虚 基 类D1nV :int nVd:intB1:nV1:intB2:nV2:intfund():voidfun():voidB1nV1 :intB2nV2 :intD1nVd :intfund():void B0nV :intfun()7.7B0B1新增成员B0B2新增成员D1新增成员B0B0B1B2D1nV,fun()65 将共同基将共同基类设置为类设置为虚基类,虚基类,这样从不这样从不同途径继同途径继承来的同承来的同名数据成名数据成员和函数员和函数成员分别成员分别只有一个只有一个拷贝。拷贝。#include using namecpace std;class B0/声明基类B0 public:/外部接口int nV;void funcoutMember of B0endl;c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论