继承是面向对象三大特征之一
有些类与类之间存在特殊的关系,如下图:
如果在定义这些类的时候发现,下级别的成员除了有上一级的共性,还存在自己的特性,这时候就可以用继承来减少代码的重复性。
一个类的对象共享了另一个类或其他多个类的成员变量和成员方法,例如:儿子继承父亲(儿子具备父亲的特征和行为),该类和另一个类或其他类的关系,称之为“继承”。
C++继承又分为单继承和多继承。
单继承:一个类的对象共享了另一个类的成员变量和成员方法
多继承:一个类的对象共享了其他多个类的成员变量和成员方法新的类我们称之为子类(派生类),已经存在的类我们称之为父类(基类)
派生类中的成员,包含两大部分:一类是继承,一类是增加
单继承的格式: class 子类 :继承方式 父类
class 新的类名(子类) : 继承的权限 已经存在的类(父类)
{ //访问权限、属性、行为都可以
//类体
};例如: class A:publicB;
A称为子类(派生类),B称为父类(基类)
多继承语法: class 子类 : 继承方式 父类1,继承方式 父类2......
(C++实际开发不建议使用 )
1、继承方式
子类继承父类有三种继承方式: (三种继承方式都不能继承父类的私有权限的东西)
1、公共继承 子类继承父类的是什么就是什么
2、保护继承 保护继承会将父类的公共权限和保护权限都改为保护权限(所继承的)
3、私有继承 私有继承会将父类的公共权限和保护权限都改为私有权限(所继承的)
这是继承的三种关系,子类所继承父类的东西
3、继承中的对象模型(就是程序中类的情况)
在父类中非静态的成员属性都会被子类继承下去,父类中的私有成员被编译器给隐藏了。故此访问不到。
4、继承中构造函数和析构函数
子类继承父类后,当创建子类的时候,也会调用父类的构造和析构函数。
继承中的构造和析构顺序如下:
先父类的构造函数、子类的构造函数、子类的析构函数、最后父类的析构函数。
5、继承中同名成员处理方式
当父类与子类出现同名的成员,如何通过子类访问子类或父类同名数据呢?
访问子类同名成员 直接访问
访问父类同名成员 需要加上作用域
例如:
cout << "子类" << s.m_A << endl;
cout << "父类" << s.Base::m_A << endl;
6、继承同名静态成员处理方式
静态成员和非静态成员出现同名时,处理方式一致。只不过有两种(对象和类名方式)
访问子类同名成员 直接访问
访问父类同名成员 需要加上作用域
7、菱形继承
概念:两个派生类(子类)继承同一个基类(父类),又有一个类继承两个派生类,就叫菱形继承或者钻石继承,如下图所示这种。
如何解决菱形继承?
利用虚继承来进行解决,既在继承之前加上关键字 virtual 变成虚继承。让两个父类的数据变为一份数据,浪费资源。
继承前加上virtual就可以变成虚继承
class 子类 : virtual 继承权限 父类 {};
class One : virtual public Animal {};