多态性
- 多态是面向对象编程的一个重要特性, 同一个实体, 多种形态.
- 面向对象编程的多态性包含
- 向不同的对象发送同一条消息, 不同的对象在接收时不会产生不同的行为, 即不同的实现, 调用不同的函数, 函数名相同, 但是执行的具体细节不同
静态多态性
-
静态多态, 也称为编译时多态, 使用函数重载的方式
-
函数重载有以下特点:
- 函数名相同
- 函数参数个数不同
- 如果函数个数相同, 参数类型不相同
- 如果函数个数 类型都形同, 那么顺序不同
- 函数重载与函数返回值无关
class GameCore{
public:
void MoveRole(Warrior& warrior);
void MoveRole(Archmage& archmage);
void MoveRole(Assassin& assa);
}
void GameCore::MoveRole(Warrior& warrior)
{
warrior.Move();
}
void GameCore::MoveRole(Archmage& archmage)
{
archmage.Move();
}
void GameCore::MoveRole(Assassin& assa)
{
assa.Move();
}
动态多态性
- 动态多态, 使用的函数重写的方式.
- 要实现C++函数重写, 必须要先把父类的成员函数设定为虚函数
- 派生类重写基类方法时可以加上override关键字, 表示重写
- override关键字为C++11标准以后新加入的, 用来明确派生类重写基类继承来的虚函数
//virtual 返回值 函数名();
class Hero
{
public:
//设定为虚函数
virtual void Move();
}
class Warrior: public Hero
{
public:
//派生类重写
void Move() override;
}
向上和向下转换
-
当B时A的子类型时(class B :public A),意味着所有对A对象的操作都可以对B对象进行, 即B重用A的操作来实现自己的操作。
-
向上转换:把子类型对象转换为父类型对象
- 向上转换是安全的
- 向上转换可以自动完成,即自动类型转换
- 向上转换的过程中,会丢失子类型信息,再调用子类的方法时编译器会报错
- 如果还想使用子类方法,就需要再进行强制转换---向下转换
-
向下转换:把父类型对象转为子类型对象
-
向下转换不安全, 因为要转换的父类对象有可能是父类型的另一个子类型
//Warrior和Archmage都是Hero的子类 Archmage warrior; Hero& hero = warrior; Warrior& newWarrior = (Warrior&)hero;
-
纯虚继承与抽象类
虚函数
- 注意:
- 构造函数不能是虚函数
- 析构函数应该是虚函数,通常基类提供一个虚析构函数,即使它不需要析构函数
- 如果基类析构函数不加virtual关键字,那么派生类对象在释放时,只会调用基类的析构;加上virtual关键字后,会先调用派生类的析构函数,再调用基类的析构函数
- 友元函数不能是虚函数, 因为友元不是类的成员
纯虚函数与抽象类
纯虚函数
- virtual 返回类型 函数名(参数列表) const = 0; 这样的虚函数就叫做纯虚函数
- 纯虚函数没有函数体,只有函数名, 不能在基类中被调用
- 纯虚函数要求必须由派生类来实现纯虚函数体的功能
抽象类
- 如果声明的类,所有的成员函数都是纯虚函数,那么该类叫做抽象类
- 抽象类用来定义业务接口,即没有实现
- 抽象类不能用来创建一个对象, 即不能实例化
- 暂时无法实现的函数,可以声明为纯虚函数,留给派生类去实现
- 设计类时,如果需要在派生类中重新定义基类方法,那么就将这个方法设置为虚方法。