继承
面向对象程序设计有4个主要特点:抽象、封装、继承、多态性。
- 继承是类之间定义的一种重要关系
- 一个B类继承A类,或称A派生类B
类A称为基类(父类),类B称为派生类(子类)
A <-- B
派生类的定义:
类继承关系的语法形式
class 派生类名:基类名
{
数据成员和成员函数声明
};
基类名表 构成
访问控制 基类名, 访问控制 基类名, …
访问控制表示派生类对基类的继承方式,使用关键字:
public 公有继承
private 私有继承
protected 保护继承
注意,C++中的继承方式(public, private, protected)会影响子类对外访问属性。
继承重要说明
- 子类拥有父类的所有成员变量和函数
- 子类可以拥有父类没有的方法和属性。
- 子类就是一种特殊的父类
- 子类对象可以当作父类对象使用
派生类的访问控制
- public 修饰的成员变量方法,在类的内部和外部都能使用
- protected 修饰的成员变量方法,在类的内部使用,在继承的子类中使用
- private 修饰的成员变量方法,只能在类的内部使用,不能在类的外部使用
protected:关键字修饰的成员变量和函数,是为了在家族中使用,是为了继承
三看原则
c++中的继承方式会y影响子类的对外访问属性
判断某一句话,能否被访问
- 看调用语句,这句话写在子类的内部、外部
- 看子类如何从父类继承
- 看父类中的访问级别
C++中的继承方式会影响子类的对外访问属性
- public继承:父类成员在子类中保持原有访问级别
- private继承:父类成员在子类中变为private成员
- protected继承:父类中public成员会变成protected
父类中protected成员仍然为protected
父类中private成员仍然为private
继承中的构造和析构
- 类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员,这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都能解决,类型兼容规则中所指的替代包括以下情况:
- 子类对象可以当作父类对象使用
- 子类对象可以是直接赋值给父类对象
- 子类对象可以直接初始化父类对象
- 父类指针可以直接指向子类对象
- 父类引用可以直接引用子类对象
在替代之后,派生类对象就可以作为基类的对象使用,但是只能使用从基类继承的成员。类型兼容规则是多态性的重要基础之一。
问题:如何初始化父类成员?父类与子类的构造函数有什么关系?
在子类对象构造时,需要调用父类构造函数对其继承得来得成员进行初始化
在子类对象析构时,需要调用父类析构函数对其继承得来的进行清理
继承中的构造析构调用原则:
- 子类对象在创建时会首先调用父类的构造函数
- 父类构造函数执行结束后,执行子类的构造函数
- 当父类当构造函数有参数时,需要在子类的初始化列表中显示调用
- 析构函数调用的先后顺序与构造函数相反
继承与组合混搭情况下,构造和析构调用原则:
- 先构造父类,再构造成员变量,最后构造自己
- 先析构自己,再析构成员变量,最后析构父类
继承中的同名成员变量处理方法
- 当子类成员变量与父类成员变量同名时
- 子类依然从父类继承同名成员
- 在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式的使用类名限定符)
- 同名成员存储在内存中不同的位置
派生类中的Static关键字
继承和static关键字在一起会产生什么现象呢?
理论知识:
基类定义的静态成员,将被所有派生类共享
根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质(遵守派生类的访问控制)
派生类中访问静态成员,用以下形式显示说明;
类名:成员
或通过对象访问 对象名 .成员
多继承的应用
多继承概念:
- 一个类有多个直接基类的继承关系成为多继承
多继承声明语法
class 派生类名: 访问控制 基类1, 访问控制, 基类2,...
{
数据成员和成员函数声明
};
- 类C可以根据访问控制同时继承类A和类B的成员,并添加自己的成员
多继承的派生类构造和访问:
- 多个基类的派生类构造函数可以用初始化调用基类构造函数初始化数据成员
- 执行顺序与单继承构造函数情况类似,多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序
- 一个派生类对象拥有多个直接或间接基类的成员,不同名成员访问不会出现二义性,如果不同的基类有同名成员,派生类对象访问时应该加以识别。