




已阅读5页,还剩42页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第八章 继承与派生 Date1 派生类的引入 C+的类提供了良好的模块分解技术 ,也具有可重用软件所期望的品质: 它们是相似一致的模块,通过信息隐 藏,将它们的接口和实现清楚地分开 来。 我们还希望在类的基础上能取得更好 的可重用性和可扩充性的目标。 面向对象的继承技术提供了实现上述目 标的有力手段。 Date2 现实中的继承与派生 在自然界中,继承这个概念是非常普 遍的。例如:小猫仔继承了猫爸猫妈 的特性,所以长的是猫鼻子猫眼,我 们不会把它错认为是小狗。 继承就是将一些本质的特性遗传给子 代,使后代在很大程度上具有与父代 相同的性质。 子代同时还具有父代没有的特性。 Date3 再来看一个现实世界中的例子: Rectangle Square Diamond ParallelogramRectangle Square Diamond Parallelogram QuadrangleQuadrangle 四边形是一个基本的概念,矩形、正方形、 菱形和平行四边形都是派生的概念,因为它 们都属于四边形,它们继承了四边形的所有 性质,同时又扩充出各自的特性。 Date4 从上面的例子可以看出: 而且子代可以拥有父代没有的特性 ,这是可扩充的概念。 一旦指定了某种事物父代的本质特 征,那么它的子代将会自动具有那 些性质。这就是一种朴素的可重用 的概念。 Date5 从软件设计的角度来看: 基于已有的类,可以建立新的类。 这个新的类既重用已有类的功能, 又扩展了新的功能。 类是某类事物共同特性的体现,它 对外提供了特定的功能。 Date6 C+的继承关系 继承就是在一个已经存在的类的基础上建 立另一个新的类。 基类 派生类 已存在的类称为“基类”或“父类”,新建立 的类称为“派生类”或“子类”,如图所示: Date7 派生类的功能主要通过以下方式来体现: 派生类的特性 吸收基类成员 添加新成员 改造基类成员 从编码的角度来看,派生类从基类中以 较低的代价换来了较大的灵活性。一旦 产生了可靠的基类,只需要调试派生类 中所作的修改即可。派生类可以对继承 的属性进行扩展、限制或改变。 Date8 单继承和多继承 单继承:派生类只有一个直接基类 A B C 单继承 XY Z 多继承 多继承:派生类有多个直接基类 Date9 单继承派生类 定义单继承派生类的语法格式: class 派生类名 : 基类名 /派生类新添加的成员 ; “继承方式”可以是public、private、 以及 protected。 虽然继承了基类的所有成员,但是派生类 并非都能访问基类的所有成员,继承方式 会影响派生类对基类中各种成员的引用。 Date10 公有派生类 在声明派生类时将继承方式指定为 public时,该类称为公有派生类。 class 派生类名 : public 基类名 /派生类新添加的成员 ; Date11 基类的成员在公有派生类中的引用权限 基类类公有成员员私有成员员保护护成员员 公有派生类类公有成员员不可访问访问 成员员保护护成员员 不可访问成员 在类外不能被直接访问。 在派生类的类内不能被直接访问 。 Date12 举例:公有派生 class Base int v1; public: int v2; Base(int a=0,int b=0) v1=a;v2=b; ; class Derived : public Base int v3; public: int v4; Derived(int a=0,int b=0) v3=a;v4=b; void func() int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; ; void main( ) Derived obj(5,6); obj.v2=8; /错 误 Date13 私有派生类 在声明派生类时将继承方式指定为 private时,该类称为私有派生类 。 class 派生类名 : private 基类 名 /派生类新添加的成员 ; Date14 基类的成员在私有派生类中的引用权限 基类类公有成员员私有成员员保护护成员员 私有派生类类私有成员员不可访问访问 成员员私有成员员 Date15 举例:私有派生 class Base int v1; public: int v2; Base(int a=0,int b=0) v1=a;v2=b; ; class Derived : private Base int v3; public: int v4; Derived(int a=0,int b=0) v3=a;v4=b; void func() int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; ; void main( ) Derived obj(5,6); obj.v2=8; /错 误 /错 误 Date16 公有派生和私有派生的比较 虽然派生类继承了基类所有的成员,但 是基类的私有成员对于派生类来说是不 可见的,因此不能被派生类所访问。 基类类公有成员员私有成员员保护护成员员 公有派生类类公有成员员不可访问访问 成员员保护护成员员 私有派生类类私有成员员不可访问访问 成员员私有成员员 Date17 保护成员的引入 为了解决这个问题,C+专门设置了 保护成员,即用protected关键字说 明的成员。 保护成员的特性: 能够被基类和派生类所访问。 和私有成员一样,类外不能访问。 Date18 举例:保护成员 class Base protected: int v1; public: int v2; Base(int a=0,int b=0) v1=a;v2=b; ; class Derived : public Base int v3; public: int v4; Derived(int a=0,int b=0) v3=a;v4=b; void func() int sum1=v1+v2+v3+v4; int sum2=v2+v3+v4; ; void main( ) Derived obj(5,6); obj.v1=8; /错 误 /正 确 Date19 保护派生类 在声明派生类时将继承方式指定为 protected时,该类称为保护派生类 : class 派生类名 : protected 基类名 /派生类新添加的成员 ; Date20 基类的成员在保护派生类中的引用权限 基类类公有成员员私有成员员保护护成员员 保护护派生类类保护护成员员不可访问访问 成员员保护护成员员 Date21 小结 不同的继承方式,子类对基类中的成 员的访问权限如下表所示: 基类类公有成 员员 私有成员员保护护成员员 公有派生类类公有成 员员 不可访问访问 成 员员 保护护成员员 保护护派生 类类 保护护成 员员 不可访问访问 成 员员 保护护成员员 私有派生类类私有成 员员 不可访问访问 成 员员 私有成员员 Date22 派生类与基类同名成员的访问方式 C+允许派生类可以重新定义基类的成 员,此时称派生类的成员覆盖了基类的 同名成员。 如果在派生类中,想使用基类的同名成 员,则可以显式地使用类名+限定符的 方式,如下所示: 基类名:成 员 Date23 举例 class Base protected: int v1; public: int v2; Base(int a=0,int b=0) v1=a;v2=b; ; class Derived : public Base int v2; public: int v3; Derived(int a=0,int b=0) v2=a;v3=b; void func() int sum1=v1+v2+v3; int sum2=v1+Base:v2+v3; ; void main( ) Derived obj(5,6); obj.v2=8; /错 误 obj.Base:v2=9; /使用的是Derived中的 v2 /使用的是Base中的v2 Date24 派生类对象的构造和析构 派生类对象数据成员的构成: 从基类继承过来的数据成员 派生类自定义的数据成员 如何初始化这几部分数据成员呢? 基本数据类型 类类型 如何析构派生类对象? Date25 单继承派生类的构造函数 派生类构造函数(参数表):基类构造函数(参数表 ), 对象成员1(参数表), 对象成员n(参数表), /初始化自定义数据成员 如果基类使用的是缺省的构造函数或不带参 数的构造函数,那么在初始化列表中可以省 略“基类构造函数(参数表)“这一项。 如果没有对象成员,那么在初始化列表中可 以省略“对象成员(参数表)“这一项。 Date26 构造函数的调用顺序如下: 构造函数和析构函数的调用顺序 先调用基类构造函数; 再调用对象成员所属类的构造函数; 最后调用派生类构造函数; 析构函数的调用顺序如下: 再调用对象成员所属类的析构函数; 先调用派生类的析构函数; 最后调用基类的析构函数; Date27 举例 class Base public: Base() cout基类对象 ”,而不是“基类对象-派生类对 象”? 其他继承方式会有以上规则吗? Date31 解决第一个问题 v1v1 v2v2 v1v1 v2v2 v3v3 v4v4 基类对象基类对象派生类对象派生类对象 基类对象和派生类对象的内存布局方式 当一个派生类对象直接赋值给基类对象时 ,不是所有的数据都赋给了基类对象,赋 予的只是派生类对象的一部分。这部分叫 做派生类对象的“切片”(sliced)。 Date32 解决第二个问题 回忆一下不同的继承方式,子类对基类中 的成员的访问权限: 基类类公有成员员私有成员员保护护成员员 公有派生类类公有成员员不可访问访问 成员员保护护成员员 私有派生类类私有成员员不可访问访问 成员员私有成员员 保护护派生类类保护护成员员不可访问访问 成员员保护护成员员 只有在公有派生的情况下,才有可能出现 “基类的公有成员变成派生类的公有成员” 的情况。 Date33 多继承派生类 派生类有多个直接基类,这叫多继承。 QuadrangleQuadrangle DiamondDiamond SquareSquare RectangleRectangle QuadrangleQuadrangle Date34 定义多继承派生类的语法格式: class 派生类名 : 基类名1, 基类名2, /派生类新添加的成员 ; Date35 多继承派生类对象的构造和析构 多继承派生类的构造函数 : 派生类名(参数表):基类名1(参数表1), 基类名2(参数表2), 对象成员1(参数表3), 对象成员2(参数表4), /派生类新添加的成员 Date36 派生类构造函数的执行顺序: 先执行所有基类的构造函数(按这些基 类被继承时声明顺序依次执行基类1、 基类2的构造函数)。 最后执行派生类本身的构造函数。 再执行对象成员所属类的构造函数(按 照这些对象成员在类中定义的顺序)。 Date37 多继承中的二义性问题 在多继承中,一个类不可以重复成为 另一个类的直接基类,但可以多次成 为间接基类。此时派生类访问基类成 员时可能出现二义性。 访问共同基类的成员时可能出现二义性。 访问不同基类的具有相同名字成员时可 能出现二义性。 Date38 访问不同基类同名成员时的二义性 class A public: int value; void f(); ; class B public: int value; void f(); void g(); ; class C: public A, public B public: void g(); void h(); ; void main() C C1; C1.f(); C1.value=9; /出现二义性 /出现二义性 解决办法是用类名对成员加以限定,例如 : C1.A:f(); 或者C1.B:f(); C1.A:value=9; 或者C1.B:value=9; Date39 访问共同基类成员时的二义性 class A public: int a; void g( ); ; class B1: public A int b1; ; class B2: public A int b2; ; class C: public B1, public B2 int c; public: int f(); ; void main() C Cobj; Cobj.a=8; Cobj.A:a=9; Cobj.g( ); /出现二义 性 /出现二义 性 /出现二义 性 解决办法:Cobj.B1:a=9;或 Cobj.B2:a=9; Date40 以上类的关系如下图所示: A(a,g() B1(b1) A(a,g() B2(b2) C(f(),c) 类A 是派生类C 两条继承路径上的一个公共基类,因此这个 公共基类会在派生类对象中产生两个基类子对象。 虽然可以通过类限定符的方式避免二义性,但问题的关键在 于我们不需要在派生类对象中存在多个基类对象的拷贝! 如果要使这个公共基类在派生类中只产生一个基类子对象, 则需要将这个基类设置为虚基类。 Date41 虚基类 引进虚基类的目的是为了解决二义性问 题,使公共基类在其派生类对象中只产 生一个基类子对象。 虚基类说明格式如下: virtual 在“继承方式”前面用关键字virtual来说明 Date42 例子:虚基类的使用 class A public: int a; void g( ); ; class B1: virtural public A int b1; ; class B2: virtural public A int b2; ; class C: public B1, public B2 int c; public: int f(); ; void main() C Cobj; Cobj.a=8; /或 Cobj.A:a=9; Cobj.g( ); Date43 A(g(),a) B1(b1)B2(b2) C(f(),c) 类A,B1,B2 和C之间的关系如下图所示: 虚基类子对象被合并成一个子对象,这种“合并” 作用,使得可能出现的二义性被消除。 Date44 请比较下面两种情况 class C: p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度市政工程土石方工程居间费管理协议
- 2025版智慧农业水果园承包种植合作协议
- 2025年度夫妻共同财产分割补充协议书
- 诸葛亮课件简介
- 诸城电脑知识培训班课件
- 2025冰箱维修维护合同范本
- 2025年个体房屋租赁合同范本
- 2025民办学校聘用专任教师合同
- 语文知识培训班开班讲话课件
- 2025年手工鞋安全生产合同
- 供电所技能竞赛装表接电技能实操试题含计算题与评分标准
- (英文简单)皇帝的新装英文剧本
- YY/T 1421-2016载脂蛋白B测定试剂盒
- 照相凹版制版法课件
- 《无人机组装与调试》课件 第一章
- 轨行区作业安全专项方案
- 科技创新领军人才申请表
- 云南省食品经营许可申请表
- 校园管制刀具排查记录表
- 财务管理学及财务知识分析笔记串讲
- 07FK02防空地下室通风设备安装PDF高清图集
评论
0/150
提交评论