1.多态的概念
多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象变成领域的核心概念。多态(polymorphion),就是多种形态。
2.多态的实现(晚绑定-->虚函数、继承)
C++多态性是通过虚函数、继承来完成的,父类对象允许子类重新定义成员函数,而子类重新定义父类的做法称为“覆盖”,或者为“重写”。
重写可以有两种:
直接重写成员函数和重写虚函数,只有重写了虚函数的话才能是体现了C++多态性。
多态和非多态的实质区别在于函数地址是早绑定还是晚绑定。如果是函数调用,在编译器编译调用期间就可以确定函数的调用地址,并且生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器确定,需要在运行时才确定,这就属于晚绑定。
3.多态的作用
那么多态的作用是什么呢?
封装使代码模块化,继承可以扩展已存在的代码,使得代码复用。而多态的目的则是:为了接口重用。也就是说:不论传递过来的究竟是那个类的对象,函数都可以通过同一个接口调用到适应各自对象的实现方法。即:当使用基类的指针或引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,指向子类调用的就是子类的虚函数。
最常用的用法就是:
声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数时,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。因为没有多态性,函数调用的地址将是一定的,而固定的地址将始终调用同一函数,这就无法实现一个接口,多种方法的目的了!
纯虚函数
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,要要求在任何派生类中都要定义自己的实现方法。在基类实现纯虚函数的方法是在函数原型后加上“=0”。
例如:
virtual void func()=0
引入原因:
为了实现多态特性,我们常常需要在基类中定义虚拟函数。
在很多情况下,基类本身生成对象是不合情理的。例如:动物作为一个基类可以派生出老虎,猴子……但是动物本身生成对象明显不合常理。
为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual return type func() = 0;)则编译器要求在派生类中必须予以重写以实现多态性。同时,含有纯虚函数的类称为抽象类,他不能生成对象。这样就很好第解决了上述两个问题。
相似概念:
1.多态性:
指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:
编译时多态性,运行时多态性。
编译时多态:通过重载实现
运行时多态:通过虚函数实现。
2.虚函数:
虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态覆盖。
3.抽象类:
包含纯虚函数的类称为抽象类。