我们之前用到的函数实现都是一个对象对应一种方法,多态就意味着一个对象对应着多种方法。那么,如何使一个对象自己可以选择所需要的函数,这就涉及到了我们说的晚绑定问题,也就是在程序运行是绑定函数地址。与之对应的静态绑定(也称早绑定)就是在程序编译的时候绑定的,要想实现多态,必须要是在晚绑定的前提下。
using namespace std;
class Person { public: virtual void gotowc() { printf(“man->left\n”);
printf("woman->right\n"); }}; class Male : public Person { public: virtual void gotowc() { printf(“man_>left\n”); } }; class Female :public Person { public: virtual void gotowc() { printf(“women->right\n”); } }; int main(void) { Person a; Male b; Female c; Person *p = &a;
p->gotowc(); p = &b; p->gotowc(); p = &c; p->gotowc(); system("pause"); return 0;}
这样当我们用不同的基类对象调用虚函数时就会产生不同的结果,从而形成多态 ①上面的代码中子类和父类当中都有相同的函数,但并不是我们之前接触到的重载和覆盖,这里又多了一个函数重写的概念,也是我们实现多态的最重要的方式。 ②重写的概念:在继承的体系下(也就是一个在父类,一个在子类)函数名,返回值,参数类型完全相同。便构成重写(协变除外),协变就是在以上条件下,俩个函数的返回值分别是自己类型的引用,虽然返回值不相同,还是构成重写。 另外, (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。 2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。 为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。 三、相似概念 1、多态性 指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。 a、编译时多态性:通过重载函数实现 b、运行时多态性:通过虚函数实现。 2、虚函数 虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态覆盖(Override) 3、抽象类 包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。