面向对象编程-4继承_第1页
面向对象编程-4继承_第2页
面向对象编程-4继承_第3页
面向对象编程-4继承_第4页
面向对象编程-4继承_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

第四章继承提纲2023/1/291派生类的构造函数与析构函数132继承方式类的继承与派生4虚基类5聚合类6继承应用实例

4.1类的继承与派生继承是软件重用的一种形式。继承是将自然界中存在的普遍和特殊关系用程序设计的方式进行分类描述在设计新类时,允许重用某个原有类的所有特征,并在此基础上添加新类的新特征被重用的原有类称为基类baseclass新创建的类称为派生类derivedclass。派生类不会影响到原有类的结构。2023/1/292

4.1类的继承与派生某一小型公司的实例:2023/1/293企业员工工作编号姓名……显示企业员工信息计算实际发放工资……行政人员(与企业员工类相同)计算实际发放工资……经理公司总销售额提成比例(其余同企业员工类)计算实际发放工资……销售人员个人销售额提成比例(其余同企业员工类)计算实际发放工资……4.1类的继承与派生针对该公司的情况:先设计一个一般员工类panyStaff,代表员工的共性;让三个新类分别继承一般员工类panyStaff,然后根据各自的差异性,新类可以对继承来的内容进行改造。2023/1/2944.1类的继承与派生派生类的定义从已有类产生新类的过程就是类的派生。定义语法如下:

class<派生类名><继承方式>:<基类名1>, <继承方式>:<基类名2>…{ <派生类成员的定义>; }2023/1/295继承方式分为三种关键字:public、private和protected;单继承(只有一个基类名)和多继承;该公司情况类代码:panyStaff.h企业员工类相关派生类经理、销售人员、行政人员这三个派生类在声明语句中分别指定了它们的基类panyStaff,以及它们的继承方式-public;CSaleManager类,同时继承经理类Cmanager和销售人员类Csaleman;CSalesmanager.h2023/1/2964.1类的继承与派生继承的级别增加行政主管一职,员工关系图如下:2023/1/297销售员经理行政主管行政人员企业员工类图4.1类的继承与派生用C++语言描述三个类的前向引用声明,形成了一个“类家族”:classpanyStaff;//基类员工//派生类行政人员继承员工classCAdminStaff:publicpanyStaff;//派生类行政主管继承行政人员classCForeAdmin:publicCAdminStaff;2023/1/2984.2继承方式基类不受派生类变化的影响派生类继承了基类的全部数据成员和除了构造函数析构函数之外的全部成员函数但是派生类能否访问基类成员还要受继承方式的约束类的继承方式有:public、private和protected三种,其中private是缺省的继承方式;2023/1/2994.2继承方式public公有继承:基类各成员的访问权限如果是public或protected,则在派生类中保持不变。而基类中的private成员对派生类不可见,如图:2023/1/29104.1类的继承与派生2023/1/2911主讲教师:四川大学计算机学院

private基类Base图3.3公有继承中的访问控制protectedpublicprivate派生类Derv:publicBaseprotectedpublicDervobjDBaseobjB4.1类的继承与派生例4.1一个公有继承的例子:sclass3_1.h

sclass3_1.cpp

smain3_1.cpp类A的所有成员在派生类中的访问控制权限都保持不变。

2023/1/29124.1类的继承与派生private私有继承:私有继承下,基类各成员无论是何种访问权限在派生类中一律以private的身份出现派生类的对象也无法访问,只有派生类的函数能在类内访问它们。私有继承后的基类成员成为了派生类的私有成员,实际上相当于终止了基类功能的继续派生2023/1/29134.2继承方式如果希望私有继承来的某些基类的成员函数在派生类中也能对外可见,就需要在派生类中对这些成员公有化class<派生类名>:private<基类名>{public: using<基类名>::<基类函数名>;//公有化

……};2023/1/29144.2继承方式例4.2私有继承中的公有化:sclass3_2.hsmain3_2.cppusingCAnimal::SetWeight;//在派生类中将基类的成员函数SetWeight()公有化

usingCAnimal::GetWeight;//在派生类中将基类的成员函数GetWeight()公有化2023/1/29154.2继承方式protected保护继承:protected继承会将基类中的public成员进行

“降权”,修改成为protected,相当于在派生类中引入了protected成员。不会降低基类的protected

成员权限。在派生类中可以调用基类类的protected和public成员,派生类的子类也可以调用被protected继承的基类的protected和public成员。例4.3保护权限举例:sclass3_3.hsmain3_3.cpp2023/1/29164.2继承方式protected保护继承下,基类各成员的访问权限(除private外)都以protected权限出现;比较私有继承和保护继承,可以看出在直接派生类中两者的效果实际上都相同,但如果再继续派生下去就会出现区别;2023/1/29174.2继承方式假设有A<-B<-C这样一个继承顺序如果B私有继承A后又派生出C,那么C就无法再间接继承A的成员,对A功能的继承在B那儿就终止了;如果B保护继承A后又派生出C,那么A中的公有和保护成员在B中都是保护成员,因此A的功能可以被C间接继承;在实际开发时选择恰当的继承方式;2023/1/29184.2继承方式多继承(多个父类):声明多继承的语法如下:class<派生类名>:<继承方式><基类名1>,<继承方式><基类名2>,…2023/1/29194.2继承方式多继承举例:在公司员工管理中有时会存在多继承关系,如图:2023/1/2920经理销售部经理销售人员4.3派生类的构造函数和析构函数构造函数:在创建派生类的对象时,系统直接执行派生类的构造函数而不会自动执行基类的构造函数;在设计派生类的构造函数时,不仅要为初始化派生类新增加的数据提供参数,而且还应为初始化基类数据成员提供参数2023/1/29214.3派生类的构造函数和析构函数相关语法:<派生类名>(<形参表>):<基类名1>(<形参表1>)<基类名2>(<形参表2>) {<派生类新增数据成员的初始化> }2023/1/29224.3派生类的构造函数和析构函数派生类构造函数的调用顺序为先父辈(基类数据)后自己(派生类新数据);轿车具有交通工具的一般特征,比如轮胎数目,同时又具有轿车自身的特征,如载客人数,因此轿车继承交通工具,成为它的一个派生类。例4.4派生类构造函数举例:sclass3_4.hsmain3_4.cpp2023/1/29234.3派生类的构造函数和析构函数派生类必须定义构造函数的两种情况:派生类新增的数据成员需要定义构造函数来为其初始化;基类定义了带参数的构造函数需要派生类为其提供参数以完成基类数据成员的初始化。2023/1/29244.3派生类的构造函数和析构函数析构函数当派生类对象消亡时,系统会自动调用派生类的析构函数做一些必要的清理工作;由于在继承过程中派生类不能继承基类的析构函数,所以如果需要就只能在派生类中重新定义;2023/1/29254.3派生类的构造函数和析构函数在执行派生类的析构函数时基类的析构函数也将被自动调用;析构函数调用的顺序是先派生类的析构函数,然后是基类的析构函数。例4.5派生类析构函数举例:sclass3_5.hsmain3_5.cpp2023/1/2926调用类A的构造函数调用类B的构造函数调用类B的析构函数调用类A的析构函数2023/1/29274.4虚基类声明一个虚基类多继承中的多义性 2023/1/29282023/1/2929AFunc()BCD该关系的C++描述:VirtualBase.h(非虚基类带来的问题)4.4虚基类作用域分辨符:可以通过作用域分辨符明确指定调用哪个类的接口;其语法形式如下:<派生类对象名>.<基类名>::<数据成员名>//访问数据成员<派生类对象名>.<基类名>::<成员函数名><参数表>//访问成员函数作用域分辨符举例:Smain3_5_B.cpp2023/1/2930基类可以将其设为虚基类,这样它的数据成员在内存中就只有一个副本,成员函数也只有一个映射从而解决了同名成员的唯一标识问题虚基类由virtual标识,声明语法如下:class<派生类名>:virtual<继承方式><基类名>;例4.6虚基类举例:sclass3_6.hsmain3_6.cpp2023/1/2931使用虚基类来定义公司员工管理系统中的多继承关系//在继承路径“销售经理—>销售人员—>员工”中将基类panyStaff设为虚基类classCSaleman:virtualpublicpanyStaff;//在继承路径“销售经理—>经理—>员工”中将基类panyStaff设为虚基类classCManager:virtualpublicpanyStaff;//派生类CSaleManager成为两条继承路径的交汇点classCSaleManager:publicCSaleman,publicCmanager;2023/1/29334.4虚基类比较使用作用域分辨符和虚基类技术:使用作用域分辨符时基类的成员在内存中存在多个副本,通过指定基类名来唯一标识使用的是哪个副本,这样可以存放不同的数据进行不同的操作;使用虚基类技术使基类的成员在内存中只存有一个副本;2023/1/29344.4虚基类虚基类的初始化:虚基类的初始化在语法上和处理一般基类一样只是调用顺序略有不同它遵循以下顺序:1)虚基类的构造函数在非虚基类之前调用;2)若同一层次中包含多个虚基类则按它们的声明顺序调用;3)若虚基类由非虚基类派生而来要先调用更高级别基类的构造函数再遵循上述1和2的顺序。

2023/1/29354.4虚基类虚基类初始化顺序的简单举例:classA;classB;classC:publicA,virtualB{};将产生如下的调用次序B()A()C()2023/1/29364.4虚基类较复杂的虚基类初始化举例:2023/1/2937

为了避免在不同继承路径中继承来的同一成员发生多个副本的冲突可以将相应的基类设为虚基类,见源代码:sclass3_7.hsmain3_7.cpp2023/1/2938classBase1classBase2classLevel2classBase2classLevel1classLeaf2023/1/29394.5聚合类聚合类的概念设计孤立的类是较容易的,难的是正确设计基类及其派生类;一般地如果在逻辑上A是B的一部分而A与B又不属于同一类范畴,则不允许B继承A的功能而是要用A和其它东西组合出B;类的聚合,就是指在一个类中内嵌其他类的对象作为成员的现象;聚合类拥有内嵌对象2023/1/2940聚合(aggregation)也是实现程序代码重用的另一有效手段;出于信息隐藏的考虑,一般都将其访问权限设为“私有”。2023/1/2941聚合类中的构造函数聚合类对象在创建时作为其组成部件的内嵌对象将首先被系统创建;如果一个聚合类,同时又是一个派生类,那么它的构造函数初始化列表还应负责为基类构造函数的调用提供参数;2023/1/2942当一个类既是聚合类又是派生类时的构造函数定义形式:<类名>::<类名><形参表><基类><

温馨提示

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

评论

0/150

提交评论