持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
多态概念
多态字面意思就是多种形态。
比如学生,成人、军人都属于人这个类。但买票时,成人买票全价,如果是学生那么半价,如果是军人,就可以优先买票。不同的人买票会有不同的实现方法,这就是多态。
C++中多态
C++的多态必须满足两个条件: 1 必须通过基类的指针或者引用调用虚函数 2 被调用的函数是虚函数,且必须完成对基类虚函数的重写
虚函数
用virtual修饰的关键字就是虚函数。 虚函数只能是类中非静态的成员函数
virtual void fun()
{}
#include <iostream>
using namespace std;
class Person //人
{
public:
virtual void fun()
{
cout << "全价票" << endl; //成人票全价
}
};
class Student : public Person //学生
{
public:
virtual void fun() //子类完成对父类虚函数的重写
{
cout << "半价票" << endl;//学生票半价
}
};
class Soldier : public Person{
public:
virtual void fun()
{
cout << "军人票" << endl;
}
};
int main()
{
Person* p1 = new Person;
p1->fun();
p1 = new Student;
p1->fun();
p1 = new Soldier;
p1->fun();
return 0;
}
/*
全价票
半价票
军人票
*/
虚函数的机制
可以使用父类类型的指针变量,里面存储子类对象的地址
Person* p1;先修一个名字叫p1的房子,用来放Person类型的地址
p1 = new Student;修一个Student类型的房子,并把Student类型的房子的地址放到p1里面去。所以运行时运行的时Student类的成员函数
p1 = new Soldier;同理
int main()
{
Person p1;
p1.fun();
p1 = Student();
p1.fun();
p1 = Soldier();
p1.fun();
return 0;
}
/*
全价票
全价票
全价票
*/
虚函数的重写
子类和父类中的虚函数拥有相同的名字,返回值,参数列表,那么称子类中的虚函数重写了父类的虚函数,或者叫做覆盖。
协变
子类的虚函数和父类的虚函数的返回值可以不同,也能构成重写。但需要子类的返回值是一个子类的指针或者引用,父类的返回值是一个父类的指针或者引用,且返回值代表的两个类也成继承关系。这个叫做协变。
class Person //人
{
public:
virtual Person* fun()
{
cout << "协变Person" << endl;
return nullptr;
}
};
class Student : public Person
{
public:
virtual Student* fun()
{
cout << "协变Student" << endl;
return nullptr;
}
};
C++11 override && final
用final修饰的虚函数无法重写。用final修饰的类无法被继承。final像这个单词的意思一样,这就是最终的版本,不用再更新了。
被override修饰的虚函数,编译器会检查这个虚函数是否重写。如果没有重写,编译器会报错。
virtual void fun() final
{
cout << "全价票" << endl; //成人票全价
}
virtual void fun() override
{
cout << "全价票" << endl; //成人票全价
}
静态类型
对象定义时的类型,编译期间就确定好了
Base base; //静态类型是Base
Derive derive; //静态类型是Derive
Base* pbase;
Base* pbase2 = new Derive();
Base* pbase3 = new Derive2();//以上三个静态类型是Base*
动态类型
对象目前所指的类型,运行时才决定的类型。一般来说,只有指针和引用才有动态类型的说法,而且一般指的是父类的指针或者引用。
pbase、derive、base没有动态类型
pbase2有动态类型,它的动态类型是Derive
pbase3有动态类型,它的动态类型是Derive2
动态类型在执行过程中可以改变
pbase = pbase2;//动态类型是Derive
pbase = pbase3;//动态类型是Derive2
总结:房子的类型是静态类型,房子里住的地址人对应的类型是动态类型
动态类型可以改变,因为子类可能不止一个