清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 第7章继承性和派生类
第7章 继承性和派生类
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 71关于继承的概念 1.基类和派生类 定义一个新类使其包含有原来类的所有成员,同 时还有自己的新成员,称这个新类是原来类的派 生类,原来类称基类。 2.单继承和多继承 只有一个基类的继承称单继承。 具有两个或两个以上的基类的继承称多继承
7.1 关于继承的概念 1. 基类和派生类 定义一个新类使其包含有原来类的所有成员,同 时还有自己的新成员,称这个新类是原来类的派 生类,原来类称基类。 2. 单继承和多继承 只有一个基类的继承称单继承。 具有两个或两个以上的基类的继承称多继承
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 3.继承的3种方式 (1)公有继承方式( public) (2)私有继承方式( private) (3)保护继承方式( protected 4.派生类的定义格式 单继承时派生类定义格式如下 clas〈派生类名〉:〈继承方式〉〈基类名〉 (派生类类体〉}; 多继承时派生类定义格式如下 class〈派生类名〉:〈继承方式1〉〈基类名1),〈继承方 式2〉〈基类名2 〈派生类类体〉};
3. 继承的3种方式 (1) 公有继承方式(public) (2) 私有继承方式(private) (3) 保护继承方式(protected) 4. 派生类的定义格式 单继承时派生类定义格式如下: class 〈派生类名〉:〈继承方式〉〈基类名〉 {〈派生类类体〉}; 多继承时派生类定义格式如下: class 〈派生类名〉:〈继承方式1〉〈基类名1〉,〈继承方 式2〉〈基类名2〉,… {〈派生类类体〉};
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 5.基类与派生类的关系 (1)派生类是基类的具体化 (2)派生类是基类定义的延续 (3)派生类是基类的组合 72基类成员在派生类中的访问权限 基类成员由于继承方式的不同在派生类中的访问权限不同, 如下表所示。 继承方式 public private pr tested Public公有 不可访问保护 Private私有 不可访问私有 Protected保护 不可访问保护
5. 基类与派生类的关系 (1) 派生类是基类的具体化 (2) 派生类是基类定义的延续 (3) 派生类是基类的组合 7.2 基类成员在派生类中的访问权限 基类成员由于继承方式的不同在派生类中的访问权限不同, 如下表所示。 继承方式 public private protected Public 公有 不可访问 保护 Private 私有 不可访问 私有 Protected 保护 不可访问 保护
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 说明: 该表第1列给出3种继承方式,该表第1行给出的是基类中的3 种访问权限。 从上表中可以看出: (1)在公有继承方式下,基类中成员在派生类中不变 (2)在私有继承方式下,基类中成员在派生类中为私有 (3)在保护继承方式下,基类中成员在派生类中为保护 无论哪种继承方式派生类都不能访问基类中私有成员。 上面是派生类对基类成员的可访问性
说明: 该表第1列给出3种继承方式,该表第1行给出的是基类中的3 种访问权限。 从上表中可以看出: (1) 在公有继承方式下,基类中成员在派生类中不变 (2) 在私有继承方式下,基类中成员在派生类中为私有 (3) 在保护继承方式下,基类中成员在派生类中为保护 无论哪种继承方式派生类都不能访问基类中私有成员。 上面是派生类对基类成员的可访问性
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 下面讨论: (1)派生类对象对基类成员的可访问性 只有公有继承方式下的基类公有成员才可访问 (2)派生类的派生类对基类成员的可访问性 在公有继承和保护继承方式下,基类中的公有成员和保护成 员都可访问。 参见[例71]、[例72]、[例73]
下面讨论: (1) 派生类对象对基类成员的可访问性 只有公有继承方式下的基类公有成员才可访问。 (2) 派生类的派生类对基类成员的可访问性 在公有继承和保护继承方式下,基类中的公有成员和保护成 员都可访问。 参见[例7.1]、[例7.2]、[例7.3]
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 73单继承的派生类的构造函数和析构函数 1.构造函数 派生类构造函数格式如下: 函数名〉(〈总参数表〉):〈基类构造函数〉(〈参数表 1)),〈子对象名〉(〈参数表2)), 〈函数体〉} 执行该构造函数的顺序是先执行基类构造函数,如有子对象 时,再执行子对象类的构造函数,最后执行该派生类构造 函数的函数体 析构函数 析构函数和构造函数都不能被继承。因此在执行派生类的析 构函数时,先调用派生类析构函数的函数体,再调用子对 象类析构函数,最后调用基类析构函数。 参见[例74]、[例7.6]
7.3 单继承的派生类的构造函数和析构函数 1. 构造函数 派生类构造函数格式如下: 〈函数名〉(〈总参数表〉):〈基类构造函数〉(〈参数表 1〉),〈子对象名〉(〈参数表2〉),… {〈函数体〉} 执行该构造函数的顺序是先执行基类构造函数,如有子对象 时,再执行子对象类的构造函数,最后执行该派生类构造 函数的函数体。 2. 析构函数 析构函数和构造函数都不能被继承。因此在执行派生类的析 构函数时,先调用派生类析构函数的函数体,再调用子对 象类析构函数,最后调用基类析构函数。 参见[例7.4]、[例7.6]
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 74子类型和赋值兼容规则 1.子类型 有一种类型A,它至少包含有另一种类B的所有行为,则称类 型A是类型B的子类型。类型A适应于类型B。子类型和类型 适应是不可逆的。 例如,在公有继承方式下,派生类是基类的子类型,派生类 适应于基类。派生类的对象是基类的对象。 2.赋值兼容规则 在公有继承方式下,派生类是基类的子类型。此时满足下述 赋值兼容规则。 ①派生类的对象可给基类对象赋值 ②派生类的对象可用来对基类对象的引用进行初始化 ③派生类的对象地址值可用来给基类的指针赋值 参见[例77]
7.4 子类型和赋值兼容规则 1. 子类型 有一种类型A,它至少包含有另一种类B的所有行为,则称类 型A是类型B的子类型。类型A适应于类型B。子类型和类型 适应是不可逆的。 例如,在公有继承方式下,派生类是基类的子类型,派生类 适应于基类。派生类的对象是基类的对象。 2. 赋值兼容规则 在公有继承方式下,派生类是基类的子类型。此时满足下述 赋值兼容规则。 ① 派生类的对象可给基类对象赋值 ② 派生类的对象可用来对基类对象的引用进行初始化 ③ 派生类的对象地址值可用来给基类的指针赋值 参见[例7.7]
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 75多继承 1.多继承的概念 单继承的很多概念适用于多继承,多继承不同于单继承的是 它具有两个或两个以上的基类。 2.多继承派生类构造函数的定义格式 〈函数名〉(〈总参数表〉):〈基类名1)〉(〈参数表1)) 〈基类名2)(〈参数表2)) 〈子对象名〉(〈参数表)), 〈派生类构造函数的函数体〉} 构造函数的执行顺序基本上与单继承构造函数的执行顺序相 同,所不同的仅仅是多个基类构造函数的执行顺序是按定 义多继承类时所给定的基类的顺序。 多继承派生类的析构函数中也应包含其基类的析构函数,该 析构函数的执行顺序与其构造函数的执行顺序相反。 参见[例78]
7.5 多继承 1. 多继承的概念 单继承的很多概念适用于多继承,多继承不同于单继承的是 它具有两个或两个以上的基类。 2. 多继承派生类构造函数的定义格式 〈函数名〉(〈总参数表〉):〈基类名1〉(〈参数表1〉)、 〈基类名2〉(〈参数表2〉)… 〈子对象名〉(〈参数表〉),… {〈派生类构造函数的函数体〉} 构造函数的执行顺序基本上与单继承构造函数的执行顺序相 同,所不同的仅仅是多个基类构造函数的执行顺序是按定 义多继承类时所给定的基类的顺序。 多继承派生类的析构函数中也应包含其基类的析构函数,该 析构函数的执行顺序与其构造函数的执行顺序相反。 参见[例7.8]
清华大学出版社 000000 TSINGHUA UNIVERSITY PRESS 7.6多继承中的二义性和虚基类 1.多继承中派生类对基类成员访问在下列两种情况下可能出 现二义性。 (1)访问不同基类的相同成员时可能出现二义性 例如,C类有两个直接基类A类和B类,其中,A类和B类中都 有一个公有成员函数f(),并且C类公有继承A和B,这时当 C类的对象c1,访问基类成员f)时,c(则会出现二义性。 为了避免出现二义性,则要用成员限定方法指出()是属于哪 个类的。即 c1A∴:f(或者c.B∷:f(
7.6 多继承中的二义性和虚基类 1. 多继承中派生类对基类成员访问在下列两种情况下可能出 现二义性。 (1) 访问不同基类的相同成员时可能出现二义性 例如,C类有两个直接基类A类和B类,其中,A类和B类中都 有一个公有成员函数f( ),并且C类公有继承A和B,这时当 C类的对象c1,访问基类成员f( )时,c1.f( )则会出现二义性。 为了避免出现二义性,则要用成员限定方法指出f( )是属于哪 个类的。即 c1.A∷f( )或者c1.B∷f( )