面向对象编程技术与方法 课件 第6章 继承与派生_第1页
面向对象编程技术与方法 课件 第6章 继承与派生_第2页
面向对象编程技术与方法 课件 第6章 继承与派生_第3页
面向对象编程技术与方法 课件 第6章 继承与派生_第4页
面向对象编程技术与方法 课件 第6章 继承与派生_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

面向对象编程技术与方法(C++)

第6章继承与派生第6章继承与派生第6章

继承与派生

6.1基类与派生类

6.2对基类成员的访问控制

6.2.1公有继承

6.2.2私有继承

6.2.3保护继承

6.3派生类的构造函数与析构函数

6.3.1构造函数

6.3.2析构函数

6.4组合与继承的选择

6.5多继承中的歧义

6.6虚基类

6.7小结

第6章继承与派生6.1基类与派生类

6.2对基类成员的访问控制6.3派生类的构造函数与析构函数 6.4组合与继承的选择 6.5多继承中的歧义 6.6虚基类 6.7小结

第6章继承与派生6.1基类与派生类继承是面向对象程序设计的基本特征之一。下面结合大学人员的例子介绍基类、派生类、派生、继承、继承方式、单继承、多继承、多重继承等概念。Student是在UnivPerson的基础上产生出的新类。UnivPerson称为Student的基类(或父类),Student称为UnivPerson的派生类(或子类)。Student继承了UnivPerson的几乎所有成员(构造函数、析构函数、赋值函数除外),并增加了新成员。这种从已有类产生新类的过程就是类的派生,从另一个角度看,从已有类获得属性和行为的过程就是类的继承。继承实现了对基类代码的重用。派生类只有一个直接基类的情况称为单继承,派生类具有多个直接基类的情况称为多继承。一个派生类同样可以作为基类,继续派生出新的类,例如在Student基础上派生graduate类。第6章继承与派生第6章继承与派生6.1基类与派生类 6.2对基类成员的访问控制 6.3派生类的构造函数与析构函数 6.4组合与继承的选择 6.5多继承中的歧义 6.6虚基类 6.7小结

第6章继承与派生6.2对基类成员的访问控制基类成员在派生类中的访问属性,不仅与它们在基类中的访问属性有关,还与继承方式有关。6.2.1公有继承1.公有继承的特点当派生类以public方式继承基类时,基类的public和protected成员在派生类中的访问属性不变,即仍为public或protected,派生类新增加的成员函数可以访问它们,但外界只可以调用派生类对象的public成员。关于基类的private成员,派生类内的成员函数不能直接访问。第6章继承与派生2.同名屏蔽现象调用派生类对象的成员函数时,如果派生类没有定义该函数,则从基类中寻找相匹配的函数,包括函数名称、返回类型、参数列表、是否带const等都要考虑。如果派生中类重新定义(Redefining)了同名函数,则编译时基类中的所有同名函数都将被屏蔽。这时,如果想调用基类中的同名函数,可以通过“基类名::”进行限制。运行结果:Base::f()Derived2::f()Base::f()Derived4::f()第6章继承与派生3.向上类型转换通过公有继承,派生类就具备了基类的功能,在需要基类对象的地方,可以用派生类对象来代替。这时存在从派生类向基类的自动转换,称为向上类型转换(upcasting),或称为类型适应。这种类型转换可能在下面情况下发生:(1)用派生类对象赋值或初始化基类对象(2)用派生类对象初始化基类引用(3)将派生类对象的地址赋给指向基类的指针由于存在向上类型转换,在这几种情况下,一般只能访问基类的成员。向上类型转换时,派生类对象中的新增成员将被舍弃,只将从基类继承来的部分赋给基类对象。这种现象称为对象切割(objectslicing)。向上类型转换是自动进行的。注意向下类型转换是不能自动进行的,即不能自动由基类转换为派生类。第6章继承与派生6.2.2私有继承当派生类以private方式继承基类时,基类的public和protected成员在派生类中的访问属性均变为private,那么派生类新增加的成员函数可以访问它们,但是外界不能访问它们。关于基类的private成员,派生类内的成员函数都不能直接访问。第6章继承与派生6.2.2保护继承当派生类以protected继承基类时,基类的public和protected成员在派生类中的访问属性均变为protected,即派生类新增成员函数可以访问它们,但外界不能访问。基类的private成员,派生类内都不能直接访问。在直接派生类中,私有继承和保护继承的作用相同:在类外不能访问任何基类成员,而派生类的成员函数可以访问基类的public和protected成员。但如果继续派生,就有所不同。如果再以公有方式派生出新类,原来私有继承的基类成员在派生类中都不可访问,原来保护继承的基类public和protected成员在派生类中具有protected访问属性,可被新类的成员函数访问。关于三种继承方式下基类成员在直接派生类中的访问属性,可以总结如表所示。第6章继承与派生第6章继承与派生6.1基类与派生类 6.2对基类成员的访问控制 6.3派生类的构造函数与析构函数

6.4组合与继承的选择 6.5多继承中的歧义 6.6虚基类 6.7小结

第6章继承与派生6.3.1构造函数由于派生类不能继承基类的构造函数,因此对继承过来的基类数据成员的初始化工作,将由派生类的构造函数来完成。在设计派生类的构造函数时,不仅要考虑派生类新增数据成员的初始化,还要考虑基类数据成员的初始化。由于派生类的const数据成员、引用型数据成员、类类型成员的初始化操作也在构造函数的初始化列表中进行。初始化列表中的执行顺序是:首先调用基类的构造函数(多个基类的初始化顺序与继承的顺序有关),然后才是派生类的成员初始化(顺序与类内的声明顺序有关)。6.3派生类的构造函数与析构函数第6章继承与派生6.3.2析构函数派生类不能继承基类的析构函数,如果需要析构的话,就要在派生类中定义自己的析构函数。上例没有显性定义析构函数,实际上是利用了编译系统自动生成的析构函数。析构的顺序与构造的顺序相反。在上例基础上,添加析构函数,参见例6-4。6.3派生类的构造函数与析构函数第6章继承与派生6.1基类与派生类 6.2对基类成员的访问控制 6.3派生类的构造函数与析构函数 6.4组合与继承的选择

6.5多继承中的歧义 6.6虚基类 6.7小结

第6章继承与派生可以看出无论是组合还是继承,结果都是把子对象放在新类型对象中,都在新类型的构造函数初始化列表中构造这些子对象。那么编程时到底应该选用那种方法呢?当新类型需要的不是已有类的接口,而是使用已有类的功能,这时应该采用组合。例如鸟与翅膀的关系,这是一种has-a的关系。当新类型需要的是已有类的接口,这时应该用继承。例如鸟与动物的关系,这是一种is-a的关系。6.4组合与继承的选择classAnimal //动物{public: voidMove()const{}};classWing //翅膀{public: voidOpen()const{} voidClose()const{}};classBird:publicAnimal //鸟是一种动物{public:

Wingwing[2]; //鸟具有一对翅膀};第6章继承与派生第6章继承与派生6.1基类与派生类 6.2对基类成员的访问控制 6.3派生类的构造函数与析构函数 6.4组合与继承的选择 6.5多继承中的歧义

6.6虚基类 6.7小结

第6章继承与派生如果一个派生类有多个基类,在这些基类中存在名字相同的成员,那么访问派生类对象的这些成员时就会出现歧义,或不确定性。classA1{public:voidf(){}};classA2{public:voidf(){};voidg(){}};classB:publicA1,publicA2{public:voidg(){}};如果主函数中有下列语句:Bb; //建立对象bb.f();//错误!//b.A1::f(); 明确指出是调用A1类的f()6.5多继承中的歧义如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类(派生类的间接基类)。这样在通过派生类对象访问间接基类的成员时,也会出现歧义。因为在派生类中存在间接基类的两份拷贝。这时同样可以用作用域运算符解决问题,如将调用“d.f();”改写为“d.B::f();”。不过在这种情况下,我们还是希望在派生类对象中只含一个间接基类的对象,即四个类之间有如图所示的继承关系,这样就避免了上面的歧义性。通过把类A声明为虚基类就可以满足这样的要求。第6章继承与派生第6章继承与派生6.1基类与派生类 6.2对基类成员的访问控制 6.3派生类的构造函数与析构函数 6.4组合与继承的选择 6.5多继承中的歧义 6.6虚基类

6.7小结

第6章继承与派生6.6虚基类声明虚基类的方法是:定义派生类时,在基类继承方式前加关键字virtual。例如:classA //定义基类{public:voidf(){};};classB:virtualpublicA //声明A为B的虚基类{//……};classC:virtualpublicA //声明A为C的虚基类

{//……};当虚基类通过多条派生路径被一个派生类继承时,该基类只被继承一次。虚基类构造函数应出现在所有派生类(直接派生类或间接派生类)构造函数的初始化列表中,如果没有显性列出,则意味着调用虚基类默认构造函数。建立派生类对象时,程序只调用虚基类的构造函数一次,而且是在调用该派生类构造函数时发生的,在调用其它中间派生类构造函数时不再调用虚基类的构造函数,从而保证虚基类子对象只被创建一次。虚基类构造函数的调用优先于非虚基类构造函数。第6章继承与派生第6章继承与派生6.1基类与派生类 6.2对基类成员的访问控制 6.3派生类的构造函数与析构函数 6.4组合与继承的选择 6.5多继承中的歧义 6.6虚基类 6.7小结

第6章继承与派生6.7小结继承与组合是两种重要的代码重用技术。单继承的派生类只有一个直接基类,多继承的派生类有多个直接基类。派生类继承了基类中除构造函数、析构函数、赋值函数之外的所有成员。这些成员在派生类中的访问属性受继承方式的影响。关于基类中的p

温馨提示

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

评论

0/150

提交评论