2. 多态的定义及实现

目录
1. 多态的概念
2. 多态的定义及实现
多态的构成条件
虚函数
虚函数的重写
特例
和 final
1. final:修饰虚函数,表示该虚函数不能再被重写
2.: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错 。
重载、覆盖(重写)、隐藏(重定义)的对比
3. 抽象类
概念
接口继承和实现继承
4. 多态的原理
虚函数表
多态的原理
动态绑定与静态绑定
5. 单继承和多继承关系中的虚函数表
6. 继承和多态常见的面试问题
1. 多态的概念
具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态 。
2. 多态的定义及实现 多态的构成条件
1. 必须通过基类的指针或者引用调用虚函数
2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写
虚函数
被修饰的类成员函数称为虚函数
class Person {public:virtual void BuyTicket() //BuyTicket()就是虚函数{cout << "买票-全价" << endl;}};
虚函数的重写
派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数 。
class Person {public:virtual void BuyTicket() //BuyTicket()就是虚函数{cout << "买票-全价" << endl;}};class Student : public Person {public:virtual void BuyTicket(){cout << "买票-半价" << endl;}};
特例
1. 协变(基类与派生类虚函数返回值类型不同)
class A {};class B : public A {};class Person {public:virtual A* f() {return new A;}};class Student : public Person {public:virtual B* f() { return new B; }};
协变: 派生类重写基类虚函数时,与基类虚函数返回值类型不同 。即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或引用
2. 析构函数的重写(基类与派生类析构函数的名字不同)
class Person{public:virtual ~Person() {cout << "~Person()" << endl; }};class Student : public Person{public:virtual ~Student(){ cout << "~Student()" << endl;}};
编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理为destr uctor 。
和 final 1. final:修饰虚函数,表示该虚函数不能再被重写
2.: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错 。

2. 多态的定义及实现

文章插图
class Traffic{public:virtual void Way() {}};class Car :public Traffic{public:virtual void Way()override { cout << "自驾" << endl; }};
重载、覆盖(重写)、隐藏(重定义)的对比
3. 抽象类 概念
包含纯虚函数的类叫做抽象类(也叫接口类),抽象类 不能实例化出对象 。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象 。
class Animal{public:virtual void Play() = 0;};class Cat :public Animal{public:virtual void Play(){cout << "睡大觉" << endl;}};class Dog :public Animal{public:virtual void Play(){cout << "出去溜达" << endl;}};void test2(){Animal* pCat = new Cat;pCat->Play();Animal* pDog = newDog;}
接口继承和实现继承
普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现 。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口 。