面向对象程序设计语言C++第06章继承和派生培训教材

上传人:yuzo****123 文档编号:141671499 上传时间:2020-08-11 格式:PPT 页数:42 大小:578KB
返回 下载 相关 举报
面向对象程序设计语言C++第06章继承和派生培训教材_第1页
第1页 / 共42页
面向对象程序设计语言C++第06章继承和派生培训教材_第2页
第2页 / 共42页
面向对象程序设计语言C++第06章继承和派生培训教材_第3页
第3页 / 共42页
面向对象程序设计语言C++第06章继承和派生培训教材_第4页
第4页 / 共42页
面向对象程序设计语言C++第06章继承和派生培训教材_第5页
第5页 / 共42页
点击查看更多>>
资源描述

《面向对象程序设计语言C++第06章继承和派生培训教材》由会员分享,可在线阅读,更多相关《面向对象程序设计语言C++第06章继承和派生培训教材(42页珍藏版)》请在金锄头文库上搜索。

1、面向对象程序设计语言C+,电子科技大学计算机学院,1,第六章 继承和派生,C+的类提供了良好的模块分解技术,也具有可重用软件所期望的品质:它们是相似一致的模块,通过信息隐藏,将它们的接口和实现清楚地分开。 但是,仅有这些是不够的,我们还希望在类的基础上能取得更好的可重用性和可扩充性的目标。 面向对象的继承技术提供了实现上述目标的有力手段。,2,第六章 继承和派生,6.1派生类的概念 6.1.1为什么要使用继承 在问题空间中,继承这个概念是非常普遍的。,3,第六章 继承和派生,6.1派生类的概念 6.1.1为什么要使用继承 在最简单的情况下,一个类B继承类A或者从类A派生类B,通常将类A称为基类

2、(父类),类B称为派生类(子类)。 这时,类B的对象具有类A对象的所有特性,甚至还会更多一些。 也可以这样说,类B从类A派生出来。这意味着类B至少描述了与类A同样的接口,至少包含了同类A一样的数据,可以共享类A的成员函数。,5,第六章 继承和派生,6.1派生类的概念 6.1.1为什么要使用继承,6,class A public: int pubA; pirvate: int priA; ;,class B : public A public: int pubB; private: int priB; ; (例6-1),class A public: int pubA; void set_pri

3、A(int a) priA=a; void set_pubA(int a) pubA=a; void out_priA() coutpriA; private: int priA;,class B : public A public: int pubB; void set_priB(int a) priB=a; void set_pubB(int a) pubB=a; void out_B() coutpubApriB; coutpubB; private: int priB; ;,void main() A objA; objA.set_priA(1); objA.set_pubA(2);

4、objA.out_priA(); B objB; objB.set_priA(3); objB.set_pubA(4); objB.set_priB(5); objB.set_pubB(6); objB.out_priA(); objB.out_B(); 程序输出为: 13456,第六章 继承和派生,6.1派生类的概念 6.1.1为什么要使用继承 类的继承,是新的类从已有的类继承已有的特征(或已有类派生出新类)。 类的派生实际是通过扩展、更改和特殊化,从一个已知类建立一个新类的过程。 通过类的派生,可以建立具有共同关键特征的对象家族,从而实现父类代码的重用。,9,这种继承和派生机制对于已有程序

5、的扩展和改进是极为有力的。 可以描述基类和派生类的关系为: 派生类是基类的具体化, 基类是派生类的抽象。 即基类综合了派生类的公共特征,派生类则在基类的基础上增加了某些特征,把抽象类变成具体的、实用的类型。,第六章 继承和派生,6.1派生类的概念 6.1.1为什么要使用继承 C+允许派生类可以重新定义基类的成员。 如果派生类定义了与基类同名的成员,称派生类的成员覆盖了基类的同名成员。 如果要在派生类中使用基类的同名成员,可以显式地使用下述类名限定符: 类名:成员 来使用基类的成员。(例6-3),11,class base2 public: int a, b; ; class derived:

6、public base public: int b, c; ; void main( ) derived d; d.a=1; d.base:b=2; / 注意base:b使用的是base类的数据成员b d.b=3; / 使用的是derived类的数据成员b d.c=4; base * bp= ,第六章 继承和派生,6.1派生类的概念 派生类可以: (1)继承基类的所有成员:将基类成员全盘吸收。这样,派生类实际上包含了他所有基类中除了构造和析构函数之外的所有成员; (2)改造基类成员:一个通过不同的派生方式改造基类成员的访问控制问题;第二个方法就是在派生类中声明一个和基类成员同名的成员覆盖基类成

7、员进行改造; (3)增加新的成员:根据派生类的实际特征,增加不同于基类的成员。,13,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 C+中,派生类的一般语法形式为 class 派生类名 : 基类类名, ; 其中: “:”后面罗列的是基类类名表,它是由“,”隔开一串元素,每个元素都是“ 基类类名”。 表示访问描述符,称为为派生方式。 派生方式有私有派生(当为private或缺省时),公有派生(当为public)和保护派生(当为protected)等三种。,14,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 1公有派生 在公有派生情况下,

8、基类保护成员和公有成员的访问权限在派生类中保持不变。即 基类的保护成员在派生类中仍然是保护成员 基类的公有成员在派生类中仍然是公有成员 基类的私有成员在派生类中成为派生类的不可访问成员 (例6-4),15,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 三个问题: 对于公有派生, 派生类的对象可不可以直接赋值给基类对象? 基类对象的引用可不可以引用一个派生类对象? 基类对象的指针可不可以指向一个派生类对象?,16,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 三个问题的具体表述如下: class Parent ; class Child

9、 : public Parent ; Child c; Parent p = c;/? Parent/?,17,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 三个问题的答案都是肯定的。,18,基类对象,子类对象,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 当一个派生类的对象直接赋值给基类对象时,很明显地,不是所有子类对象的东西都赋给了父类对象,赋予的只是子类对象的一部分。这叫做子类对象的“切片(sliced)”。 需要注意的是,如果在三个问题中将父类和子类的位置反过来,那么问题的答案就是全否定。,19,第六章 继承和派生,6.1派生

10、类的概念 6.1.2 派生类的声明和继承方式 2. 私有派生 如果 为 private(或缺省),那么: 基类的保护成员在私有派生类中是私有成员; 基类的公有成员在私有派生类中是私有成员; 基类的私有成员和不可访问成员在私有派生类中成为派生类的不可访问成员。 也就是说,私有派生之后,基类的成员就再也无法在以后的派生类中发挥作用,相当于阻止了基类功能的继续派生。(例6-5),20,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 3. 保护派生 C+语言还允许保护派生方式。 保护派生方式下,基类的所有公有段成员和保护段成员都成为保护派生类保护段的成员; 基类的私有成员和

11、不可访问成员在保护派生类中成为派生类的不可访问成员。 保护派生方式一般很少使用。,21,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式,22,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 4.静态成员的派生 static成员受段约束符的限制,基类和派生类共享基类的static成员。 要求访问静态成员时,必须用“类名:成员”显式地说明。(例6-7),23,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 5.访问声明 类 D 从基类B私有派生,因而类D的派生类E不能访问间接基类 B 的所有成员。 但有些时侯,这种

12、”一刀切”的方法会带来问题。为了满足这种需要,C+提供了一种调节机制,称为访问声明,它使得 B 的某几个成员能被类 E 所访问。,24,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式 访问声明的形式为: (1)基类类名:基类保护段或公有段数据成员; (2)基类类名:基类保护段或公有段成员函数名;,25,class B int a; public: int b; void f(); ;,class D : private B int d; public: B:b; B:f; int c; ;,第六章 继承和派生,6.1派生类的概念 6.1.2 派生类的声明和继承方式

13、对访问声明的使用需要注意以下几点: (1)访问声明不能说明任何类型。 (2)访问声明仅用于派生类中恢复名字的访问权限,不允许在派生类中降低或提升基类成员的可访问性。 (3)对重载函数名的访问声明将调整基类中具有该名的所有函数的访问域。,26,第六章 继承和派生,6.1派生类的概念 6.1.3基类对象的初始化 1.类等级 下面是一个继承链中的类等级图示:,27,要在派生类中访问与派生类同名的基类成员,采用 类名:成员 的方式。(例6-12),第六章 继承和派生,6.1派生类的概念 6.1.3基类对象的初始化 2. 基类对象的初始化 在 C+ 中,派生类构造函数的声明为: 派生类构造函数(变元表)

14、:基类(变元表),对象成员1(变元表),对象成员n(变元表) ; 构造函数执行时仍遵循先兄长(基类),再客人(对象成员),后自己(派生类)的顺序。 另一方面,执行析构函数时,先执行派生类的析构函数,再执行基类的析构函数。(例6-13-16),28,第六章 继承和派生,6.2多继承 6.2.1多继承的概念 至今所看到的例子中,派生类仅有一个直接基类,这称为单继承。但是一些类却代表两个或多个类的合成。 例如,两用沙发,它是一个沙发,也是一张床,两用沙发应允许同时继承沙发和床的特征,即SleepSofa继承Bed和Sofa两个类,因此多继承是指一个派生类有两个或者两个以上的直接基类。(例6-17),

15、29,第六章 继承和派生,6.2多继承 6.2.1多继承的概念,30,第六章 继承和派生,6.2多继承 6.2.2虚基类 1.虚基类的概念 在 C+ 中,一个类不能被多次说明为一个派生类的直接基类,但可以不止一次地成为间接基类。这就导致了一些问题。为了方便说明,先介绍多继承的“类格”表示法。 派生类及其基类可用一有向无环图( DAG )表示,其中的箭头表示“由派生而来”。类的 DAG 图常称为一个“类格”。,31,第六章 继承和派生,6.2多继承 6.2.2虚基类 class L public: int next; ; class A : public L ; class B : public

16、 L ;,32,class C : public A, public B public: void f() next = 0; ;,第六章 继承和派生,6.2多继承 6.2.2虚基类,33,第六章 继承和派生,6.2多继承 6.2.2虚基类 当在多条继承路径上有一个公共的基类(如本例的 L ),在这些路径中的某几条路径汇合处(如本例中的 C ),这个公共基类就会产生多个实例。 也就是说,如果L中有一个叫做next的成员,那么在C中就有两个叫做next的成员。那么,下面的代码在编译时就会引起二义性错误: C Obj; Obj.next = 0; 而这条使正确的:Obj.A:next = 0;,34,第六章 继承和派生,6.2多继承 6.2.2虚基类 如果只想保存这个基类的一个实例,可以将这个公共基类说明为虚拟基类或称虚基类。它仅是简单地将关键字virtual加到基类的描述上,例如改写上述例子为: clas

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 教学课件 > 高中课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号