版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章第七章 继承与派生继承与派生本章主要内容本章主要内容1. 类的继承与派生的提出2. 派生类的定义与相关概念3. 三种基本继承方式4. 派生类的构造与析构函数5. 派生类的成员标示与访问6. 虚基类7. 赋值兼容规则类的继承与派生的提出类的继承与派生的提出问题:问题:1.我会使用windows98 ,我需要重新学习XP操作系统吗?2.我定义了一个描述点的类,如何在定义一个描述矩形的类?现实思维模现实思维模式式.WH事物发展事物发展有其延续有其延续性!性!类的继承与派生的提出类的继承与派生的提出 继承的目的继承的目的:实现数据、代码的重用。 派生的目的派生的目的:当新的问题出现,原有程序无法
2、解决(或不能完全解决)时,需要对原有数据、代码进行改造。 返返 回回派生类的定义与相关概念派生类的定义与相关概念定义格式:定义格式:class 派生类名:继承方式1 基类名1,继承方式n 基类名n成员声明; 注:继承方式注:继承方式1. 公有继承public2. 私有继承private3. 保护继承protected1.保持已有类的特性而构造新类的过程称为保持已有类的特性而构造新类的过程称为继承继承。2.在已有类的基础上新增自己的特性而产生新类的过程称为在已有类的基础上新增自己的特性而产生新类的过程称为派生派生。3.被继承的已有类称为被继承的已有类称为基类基类(父类)。(父类)。4.派生出的新
3、类称为派生出的新类称为派生类派生类(子类子类)。5.直接父类、直接父类、直接直接子类;间接父类、子类;间接父类、间接间接子类子类派生类的定义与相关概念派生类的定义与相关概念派生(继承)的内部实现过程:派生(继承)的内部实现过程: 添加新成员添加新成员 吸收除构造、析构吸收除构造、析构函数外基类成员函数外基类成员 改造基类成员改造基类成员派生类的定义与相关概念派生类的定义与相关概念描述平面的一个点 矩形定义简单实例:简单实例:class pointpublic:point(int a,int b)x=a,y=b;int getx()int gety()void moveto(int a,int
4、b )private:int x,int y;class rectangle:public pointpublic:public retangle(int x,int y, int width,int heigth):point(x,y)w=width;h=height;privated:int w,h;派生类的定义与相关概念派生类的定义与相关概念基类与派生类的对应关系基类与派生类的对应关系:1.单继承:派生类只从一个基类派生。2.多继承:派生类从多个基类派生。3.多重派生:由一个基类派生出多个不同的派生类。4.多层派生:派生类又作为基类,继续派生新的类。 简化的继承体系图简化的继承体系图返返
5、 回回三种基本继承方式三种基本继承方式1. 公有继承公有继承(public)1) 基类的public和protected成员的访问属性在派生类中保持不变;基类的private成员不可访问(类内类内) 2) 派生类的对象只能访问基类的public成员(类外类外) class Apublic:int x;A(int a,int b)x=a;u=b;void prt() coutpublic x=: xendl;private:int u; 举例举例 第一步:定义基类:第一步:定义基类:举例举例 第二第二 步:定义派生类步:定义派生类class B:public Apublic: B(int a,i
6、nt b,int c):A(a,b)y=c; int y; void prt() coutA:x= :A:xendl;A:prt(); /cout private base A:u=A:uendl;cout B:y=:yendl;此行错误!此行错误!举例举例 第三步:使用派生类第三步:使用派生类void main()B b(1,2,3);b.prt();/coutb.uendl;运行结果:运行结果:A:x= :1public x=: 1 B:y=:31Press any key to continueError!不可直接输出u.1)派生类中:基类public和protected成员变成priv
7、ate成员;基类private成员不可访问。2)通过派生类的对象不能访问基类中的任何成员2. 私有继承私有继承(private)如何理解?类外的问题class Apublic:int x;A(int a,int b)x=a;u=b;void prt() coutpublic x=: xendl;private:int u;举例举例 第一步:定义基类:第一步:定义基类:举例举例 第二第二 步:定义派生类步:定义派生类class B:private Apublic: B(int a,int b,int c):A(a,b)y=c; int y; void prt() coutA:x= :A:xend
8、l;A:prt();cout B:y=:yendl;举例举例 第三步:使用派生类第三步:使用派生类void main()B b(1,2,3);b.prt();/coutb.xendl;运行结果:运行结果:A:x= :1public x=: 1 B:y=:31Press any key to continue私有数据,不可直接输出b.3. 保护保护继承继承(public)1) 派生类中:基类的public和protected成员变成protected成员;基类的private成员不可访问2) 派生类的对象不能访问基类中的任何成员protected 成员举例成员举例class A protecte
9、d: int x;int main( ) A a; /a.X=5; 错误protected 继承class Apublic: int x void show_private()coutprivate of As y=y; void show_proteced()coutprotected of As z=z;private: int y; protected: int z;class B : protected Apublic :void out_base_public()coutx=:xendl;/void out_base_private()couty=:yendl; Error!void
10、 out_base_proteced()coutz=:zendl;void main()B b;/ b.x=19; Errror/ b.y=19; Error/ b.z=19; Errorb.out_base_public();b.out_base_proteced();如何访问如何访问A中的中的X、y、z?如何输出如何输出A中的中的私有成员私有成员?间接的方式间接的方式三种继承方式之间的比较三种继承方式之间的比较返返 回回派生类的构造与析构函数派生类的构造与析构函数一、构造函数一、构造函数1. 基类的构造函数不被继承,需要在派生类中自行声明2. 初始化完成:1. 基类成员:基类构造函数完成2
11、. 内嵌对象成员3. 新增成员顺序的思考:顺序的思考:有它的现实有它的现实原形么?原形么?格式:格式:派生类名:派生类名(参数总表):基类名1(参数), 基类名2(参数), .基类名n(参数),内嵌对象1(参数)内嵌对象n(参数)本类成员初始化赋值语句;派生类的构造函数派生类的构造函数注意:注意:参数的顺序不重要参数的顺序不重要对比组合类的对比组合类的构造函数构造函数构造函数的调用次序构造函数的调用次序1.调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左向右)。2.调用成员对象的构造函数,调用顺序按照它们在类中声明的顺序。3.派生类的构造函数完成新增成员的初始化。注意注意:派生类的析
12、构函数的调用次序与构造函数正:派生类的析构函数的调用次序与构造函数正好相反好相反为什么?举例举例:讨论构造函数的调用次序问题讨论构造函数的调用次序问题class B1/基类B1,构造函数有参数public:B1(int i) coutconstructing B1 iendl;class B2/基类B2,构造函数有参数public:B2(int j) coutconstructing B2 jendl;class B3/基类B3,构造函数无参数public:B3( )coutconstructing B3 *endl;class C: public B2, public B1, public
13、B3 public:C(int a, int b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b) private:B1 memberB1;B2 memberB2;B3 memberB3;void main( ) C obj(1,2,3,4);认真思考并回答其输出结果?constructing B2 2constructing B1 1constructing B3 *constructing B1 3constructing B2 4constructing B3 *Press any key to continue对构造函数调用的讨论对
14、构造函数调用的讨论1. 基类采用缺省构造函数时:派生类构造函数可以调用基类缺省构造函数。2. 基类声明带形参的构造函数时,派生类传递参数给基类构造函数,完成基类成员的初始化1. 自定义缺省构造函数:1.无参数 2.带缺省值2. 系统默认构造函数两种情形两种情形二、析构函数二、析构函数1.析构函数也不被继承,派生类自行声明2.声明方法与一般(无继承关系时)类的析构函数相同3.不需要显式地调用基类的析构函数,系统会自动隐式调用和组合类相似二、析构函数二、析构函数1.析构函数的调用次序与构造函数相反 2.自定义析构函数主要完成动态分配内存对象的释放举例:举例:class B1/基类B1声明publi
15、c: B1(int i)coutconstructing B1 iendl; B1() coutdestructing B1 endl;class B2/基类B2声明public: B2(int j)coutconstructing B2 jendl; B2() coutdestructing B2 endl;class B3/基类B3声明public: B3()coutconstructing B3 *endl; B3() coutdestructing B3 endl;class C: public B2, public B1, public B3public: C(int a, int
16、b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b)private:B1 memberB1;B2 memberB2;B3 memberB3;void main()C obj(1,2,3,4); 输出结果:输出结果:Constucting B2 2Constucting B1 1Constucting B3 *Constucting B1 3Constucting B2 4Constucting B3 *Destructing B3Destructing B2Destructing B1Destructing B3Destructing B1
17、Destructing B2返返 回回派生类的成员标示与访问派生类的成员标示与访问问题:问题:1.当派生类与基类中有相同成员时,如何标示与访问不同类中定义的成员?举例:举例:class B1 public: int nV;void fun( );class D1: public B1 public:int nV;void fun ( )如何访问如何访问D1类中、对象中成员?类中、对象中成员?看下页派生类的成员标示与访问派生类的成员标示与访问同名覆盖原则同名覆盖原则当派生类与基类中有相同成员时:1.若未强行指名,则通过派生类对象使用的是派生类中的同名成员。2.如要通过派生类对象访问基类中被覆盖的
18、同名成员,应使用基类名限定。void main( ) D1 d1;d1.nV=1; /对象名.成员名标识, 访问D1类成员,同名覆盖d1.fun( ); d1.B1:nV=2;/作用域分辨符标识, 访问基类B1成员d1.B1:fun( );派生类的成员标示与访问派生类的成员标示与访问消除二义性消除二义性 2.当多个直接基类中都从某一间接基类继承共同成员时如何标示和访问?(参见下页图)(参见下页图)问题:问题:问题越来越问题越来越复杂啦!复杂啦!看下页Class B0Public:Int nvVoid fun()class B1:public B0public: int nV1;void fun
19、1( );class B2:public B0 public:int nV2;void fun2( );class D1: public B1,public B2 public:int nV;void fun*( )派生类的成员标示与访问派生类的成员标示与访问解决解决二义性问题 通过直接基类,使用作用域运算符来访问不同类中的成员参照上页图示参照上页图示 D1.B1:nv=1; D1.B2:nv=2; 声明虚基类(下节介绍)返返 回回虚基类虚基类1. 虚基类的引入:用于直接基类有共同基类的场合,2. 防止多次初始化基类成员,实现维护一份拷贝3. 声明:继承时以virtual修饰说明基类例:cla
20、ss B1:virtual public B注意:在第一级继承时就要将共同基类设计为虚基类。注意:在第一级继承时就要将共同基类设计为虚基类。下页举例虚基类举例:虚基类举例:class B0/声明基类B0public:/外部接口int nV;void fun( )coutMember of B0endl;class B1: virtual public B0 /B0为虚基类public:/新增外部接口int nV1;class B2: virtual public B0 /B0为虚基类派生B2类 public:/新增外部接口int nV2;class D1: public B1, public
21、B2/派生类D1声明 public:/新增外部接口int nVd;void fund( )coutMember of D1endl;存储映象存储映象虚基虚基类类void main( )/程序主函数 D1 d1;/声明D1类对象d1d1.nV=2;/使用直接基类数据成员d1.fun( );/ 使用直接基类函数成员使之虚的思想使之虚的思想虚基类及其派生类构造函数虚基类及其派生类构造函数1.建立对象的类称为最远派生类2.虚基类成员由最远派生类构造函数通过虚基类构造函数进行初始化虚基类及其派生类构造函数虚基类及其派生类构造函数3.派生类在构造函数的成员初始化表中调用虚基类的构造函数。否则调用该虚基类的
22、缺省构造函数4.C保证最远(当前)派生类的构造函数调用虚基类的构造函数,忽略其它父类对虚基类构造函数的调用避免多次构造class B0/声明基类B0 public:/外部接口 B0(int n) nV=n; int nV; void fun( );class B1: virtual public B0 public:B1(int a) : B0(a) int nV1;class B2: virtual public B0 public:B2(int a) : B0(a) int nV2;直接基类与间接基直接基类与间接基类定义类定义class D1: public B1, public B2public:D1(int a) : B0(a), B1(a), B2(a)int nVd;void fund( )coutMember of D1endl;void main( )D1 d1(9);d1.nV=2;d1.fun( );派生类定义派生类定义返返 回回赋值兼容原则赋值兼容原则一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。具体表现在:1. 派生类的对象可以被赋值给基类对象2. 派生类的对象可以初始化基类的引用3. 指向基类的指针也可以指向派生类的对象对比类型转换在Vc等可视化开发工具中大量使用!举例举例:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年安全意识提升课件
- 尿管留置的并发症护理措施
- 2026广西南宁市五一路小学春季学期临聘教师招聘考试备考试题及答案解析
- 2026广东江门市东林物业管理有限公司招聘25人笔试备考题库及答案解析
- 中医护理实践中的创新思维培养
- 2026四川安吉物流集团有限公司上半年社会招聘23人(一)考试参考试题及答案解析
- 2026四川德阳市人民医院招聘5人考试参考试题及答案解析
- 2026天津市河东区东新街社区卫生服务中心招聘编外工作人员1人考试参考题库及答案解析
- 2026广西百色市西林县就业服务中心招聘编外聘用人员2人考试备考试题及答案解析
- 2026年合肥市园上园小学学府路校区2025-2026学年第二学期教师招聘补招笔试备考试题及答案解析
- 2025年枣庄科技职业学院高职单招语文2018-2024历年参考题库频考点含答案解析
- 眼科日间手术流程标准化管理
- 2024年长沙民政职业技术学院单招职业技能测试题库及答案解析
- ABB工业机器人应用技术 故障诊断与维护 课件全套 杨金鹏 项目1-4 工业机器人的安全作业事项- 工业机器人本体的维护
- 大学英语第1堂课自我介绍课程介绍
- 物流无人机垂直起降场选址与建设规范
- 回肠膀胱造口术后护理
- 中小学生森林防火安全教育《保护森林 人人有责》课件
- 宫颈癌科普知识讲座
- 《园艺植物生物学》课件
- 离心泵安装单元工程质量验收评定表
评论
0/150
提交评论