1.多态的概念
多态,就是不同对象去完成某一种行为时,产生的不同状态。
举例说明:日常生活中,我们去买票,尤其买火车票时,总会有不同的结果。当成人买的时候,就是原价,学生就是半价,军人就是优先买票,这都体现了多态。不同对象完成某一行为,产生不同状态。
那实现多态前,我们首先得清楚一些概念:
1.1虚函数
虚函数:即被virtual修饰的类成员函数称为虚函数。
class A { public: virtual void func() { cout << "A" << endl; } };
1.2虚函数的重写
我们之前在继承的时候,学习过重定义(隐藏),现在在多态这一节,又出现了重写,那到底是什么呢?我们来看一看
重定义(隐藏):首先在两个不同的类中(父类,子类)(构成继承),只要函数名相同,就会构成重定义(隐藏)。
重写(覆盖):在重定义的基础上,除了函数名要相同,还有返回值,参数都得相同,这才构成重写。
举个例子:
—
class A { public: virtual void func() { cout << "A" << endl; } }; class B:public A { public: virtual void func() //重写 { cout << "B" << endl; } };
总结就是:虚函数的重写条件:子类和父类都是虚函数,且函数名,返回值,参数都必须相同(三同),这才能构成虚函数的重写。
1.3虚函数重写的两个例外
1.子类的虚函数可以不加virtual
因为是继承关系,父类的虚函数也被继承下来,所以子类的可以不加virtual。(建议还是都写上)
class A { public: virtual void func() { cout << "A" << endl; } }; class B:public A { public: void func() { cout << "B" << endl; } };
2. 协变(基类与派生类虚函数返回值类型不同)
意思是:三同中,返回值可以不同,但要求返回值必须是父子类关系的指针或引用。(其他父子类关系的指针或者引用也可以)
class person { public: virtual person* func() //本父子类指针或引用 { return this; } }; class student:public person { public: virtual student* func() //本父子类指针或引用 { return this; } };
、其他父子类关系的指针或者引用也可以:
class A {}; class B:public A {}; class person { public: virtual A* func() { return nullptr; } }; class student:public person { public: virtual A* func() { return nullptr; } };
但是父类的返回值不可以为子类的指针。
1.4如何实现一个不能被继承的类
方法一:是需要把它的构造函数写为私有即可,无法构造,就不可能被继承;
方法二:类定义时,加final(c++11),最终类,不能被继承
class A final {}; class B:public A {};
若final给虚函数,虚函数则不能被重写
class A { virtual void func()final {} }; class B:public A { virtual void func() {} };
override是来判断是否已经重写(检查重写)
class A { virtual void func(int) {} }; class B:public A { virtual void func()override {} };