多态分为两类:
- 静态多态:函数重载 和 运算符重载 属于静态多态,复用函数名
- 动态多态:派生类和虚函数实现运行时多态
静态多态和动态多态区别: - 静态多态的函数地址早绑定,编译阶段确定函数地址
- 动态多态的函数地址晚绑定,运行阶段确定函数地址
满足条件:
- 有继承关系
- 子类要重写父类中的虚函数(注意和重载不同,重载就是函数名一样,参数可以不同)
(重写:函数返回值类型,名称,参数列表 完全相同)
动态多态使用:
父类的指针或引用 指向子类对象
//动物类
class Animal
{
public:
virtual void speak()//加上virtual称为虚函数
{
cout << "动物在说话" << endl;
}
};
//小猫类
class Cat:public Animal
{
public:
void speak()//重写父类虚函数,这里的virtual可写可不写
{
cout << "小猫说话喵喵喵" << endl;
}
};
class Dog :public Animal
{
public:
void speak()//重写父类虚函数
{
cout << "小狗汪汪汪" << endl;
}
};
//执行说话的函数
//地址早绑定,在编译阶段确定地址
//如果想执行让猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段绑定
void doSpeak(Animal& animal)//Animal &animal = cat 理解为,cat继承了anaimal,即派生类继承了基类,我们可以把派生类的对象当成基类对象来使用
{
animal.speak();
}
int main()
{
Animal ai;
doSpeak(ai);
Cat cat;
doSpeak(cat);
Dog dog;
doSpeak(dog);
return 0;
}
这里,cat继承了anaimal,即派生类继承了基类,我们可以把派生类的对象当成基类对象来使用,即把cat当成animal来使用。而且我们可以把基类的指针或引用绑定到派生类对象中的基类部分上。