目录
一.多态的概念
多态
举例.我们在买票时会有成人票和儿童票,成人票的价格和儿童票的价格不一样,我们需要去区分成人票和儿童票,当然也有可能有其他的票型,这就很麻烦.我们就需要使用多态来处理
概念:当不同对象完成同一个操作是,会产生不同的结果,这就是多态,简单点来说就是,基类指针/引用指向子类对象.
那我们为什么要使用多态呢?(必要性)
原因:我们知道继承和封装都为了实现代码的复用性,多态也可以实现代码复用.还可以解决项目程序中紧耦合的问题,提高程序的可扩展性.代码中尽量使用接口去访问而不是随意使用其成员变量.
多态的好处?
派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性.
那么如何实现多态呢?
实现多态有连两个要点:
- 必须通过基类的指针/引用指向子类对象去调用虚函数
- 被调用的函数必须是虚函数,而且基类的虚函数被子类重写.
我们将被virtual修饰的函数叫做虚函数.//这里与虚继承使用同一个关键字,但是并没有关系
public:
virtual void buyTicket()
{
cout << "成人票" << endl;
}
那么重写又是什么呢?
重写:也叫隐藏,是派生类中有一个跟基类完全相同的虚函数称子类的虚函数重写了基类的虚函数。(协变允许返回值不同)
这有一个例子实现多态
#include<iostream>
using namespace std;
class Person
{
public:
virtual void buyTicket() {
std::cout << "成人票" << std::endl;
}
};
class Student : public Person
{
public:
void buyTicket() {
std::cout << "学生票" << std::endl;
}
};
void Func(Person& p) {
p.buyTicket();
}
void main() {
Person p;
Student s;
Func(p);
Func(s);
}
这里不同的身份票买的不一样的.,这里子类的虚函数重写了父类的虚函数,实现了多态
协变
允许重写的函数返回值不同的操作,派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时称为协变。
析构函数的特殊处理
为什么要对析构函数特殊处理?
看这个例子
class Person
{
public:
~Person() { cout << "~Person()" << endl; }
};
class Student : public Person
{
public:
~Student() { cout << "~Student()" << endl; }
};
int main() {
Person *p1 = new Person;
Person *p2 = new Student;
delete p1;
delete p2;
return 0;
}
运行结果:我们发现不重写的析构函数是不会调用子类的析构函数的,也就是说当我们开辟一个子类对象,赋值给父类时,当其声明周期结束的时候,子类中的资源是不会释