- 前言
- 1.继承和派生
- 2.三种继承方式
- 3.子类的构造函数与析构函数
- 3.1 子类和父类构造(析构)函数的调用顺序
- 3.1.1 构造函数的调用顺序
- 3.1.2 析构函数的调用顺序
- 3.2 在子类构造函数中调用父类构造函数
- 4.子类型关系
- 4.1 子类型关系的概念
- 4.2 子类型作用
- 4.3 子类型的应用
前言
本篇文章主要介绍了类的继承与派生
1.继承和派生
(1)继承和派生是从不同角度来描述一个类从另一个类获取成员变量和成员函数的过程。
(2)被继承的类称为父类或基类,继承的类称为子类或派生类。
(3)派生类除了拥有基类的成员,还可以定义自己的新成员,以增强类的功能。
//继承和派生的一般语法:
class 派生类名:继承方式 基类名{
派生类新加成员
}
两种典型的使用继承的场景:
1) 当创建的新类与现有的类相似,只是多出若干成员变量或成员函数时,可以使用继承,这样不但会减少代码量,而且新类会拥有基类的所有功能。
2) 当需要创建多个类,它们拥有很多相似的成员变量或成员函数时,也可以使用继承。可以将这些类的共同成员提取出来,定义为基类,然后从基类继承,既可以节省代码,也方便后续修改成员。
2.三种继承方式
1) public继承方式
基类中所有 public 成员在派生类中为 public 属性;
基类中所有 protected 成员在派生类中为 protected 属性;
基类中所有 private 成员在派生类中不能使用。
2) protected继承方式
基类中的所有 public 成员在派生类中为 protected 属性;
基类中的所有 protected 成员在派生类中为 protected 属性;
基类中的所有 private 成员在派生类中不能使用。
3) private继承方式
基类中的所有 public 成员在派生类中均为 private 属性;
基类中的所有 protected 成员在派生类中均为 private 属性;
基类中的所有 private 成员在派生类中不能使用。
基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了(但是,可以调用方法使用)。
使用 using 关键字可以改变基类成员在派生类中的访问权限,例如将 public 改为 private、将 protected 改为 public。
using 只能改变基类中 public 和 protected 成员的访问权限,不能改变 private 成员的访问权限,因为基类中 private 成员在派生类中是不可见的,根本不能使用,所以基类中的 private 成员在派生类中无论如何都不能访问。
//基类
class Father{
public:
void fatherFun();
protected:
string name;
int age;
}
//派生类
class Son:
public Father
{
public:
void sonFun();
public:
using Father::name;//将protected改为public
private:
using Father::fatherFun;//将public改为private
}
3.子类的构造函数与析构函数 3.1 子类和父类构造(析构)函数的调用顺序 3.1.1 构造函数的调用顺序
当创建子类对象时, 构造函数的调用顺序:
静态数据成员的构造函数 -> 父类的构造函数 -> 非静态的数据成员的构造函数 -> 自己的构造函数
注意:
无论创建几个对象, 该类的静态成员只构建一次, 所以静态成员的构造函数只调用1次!!!
子类的析构函数的调用顺序,和子类的构造函数的调用顺序相反
静态对象在程序终止时被销毁,所以:静态成员的析构函数,在程序结束前,是不会被调用的!
class Son : public Father {
public:
// 在子类的构造函数中,显式调用父类的构造函数
Son(const char *name, int age, const char *game)
:Father(name, age) {
this->game = game;
}
// 没有显式的调用父类的构造函数,那么会自动调用父类的默认构造函数
Son(const char *name, const char *game){
this->game = game;
}
};
4.子类型关系 4.1 子类型关系的概念
子类型:派生类是基类的子类型
子类型关系具有单向传递性(C是B的子类型,B是A的子类型,那么C是A的子类型)。
在需要父类对象的任何地方, 可以使用”公有派生”的子类的对象来替代,
从而可以使用相同的函数统一处理基类对象和公有派生类对象
即:形参为基类对象时,实参可以是派生类对象
1. 基类(父类)的指针,可以指向这个类的公有派生类(子类型)对象。
Son obj; Father * f = &obj;
2. 公有派生类(子类型)的对象可以初始化基类的引用
Son obj; Father &f = obj;
3. 公有派生类的对象可以赋值给基类的对象
Son obj; Father f = obj;
注意:以上应用反过来就会导致编译失败,父类是不能替换为子类的



