多态性
一:什么是多态?
简单来说多态是“一个接口,多种方法”。(不同对象收到相同的消息时,产生不同的动作)。
从实现角度来讲,多态可以划分为两类:编译时的多态(通过静态连编实现,主要通过函数重载和运算符重载实现)和运行时的多态(通过动态连编实现,主要通过虚函数实现)。
二:重载和覆盖有什么不同?
虚函数总是在派生类中被改写,这种改写被称为“Override”(覆盖)。它是指派生类重写基类的虚函数,重写的函数必须有一致的参数表和返回值。
Overload被称为“重载”,是指编写一个与已有函数同名但是参数表不同的函数。函数重载是编译时的多态。
#include<iostream> using namespace std; class Base{ public: virtual void f1(); virtual void f2(); virtual void f3(); void f4(); }; class Derived:public Base{ public: virtual void f1();//虚函数,可以不写virtual void f2(int x);//失去虚函数的特性,编程普通的重载函数 //char f3();//返回值不一样,编译出错 void f4();//普通的重载函数 }; void Base::f1() { cout<<"base1\n"; } void Base::f2() { cout<<"base2\n"; } void Base::f3() { cout<<"base3\n"; } void Base::f4() { cout<<"base4\n"; } void Derived::f1() { cout<<"Derived1\n"; } void Derived::f2(int x) { cout<<"Derived2\n"; } void Derived::f4() { cout<<"Derived4\n"; } int main() { Base b,*p; Derived d; p=&d; p->f1(); p->f2(); p->f4(); return 0; }
结果:
三:纯虚函数和抽象类
1)纯虚函数:
有时,基类往往便是一种抽象的概念,它并不与具体的事物相联系。 这时在基类中将某一成员函数定义为虚函数,并不是基类本身的需要,而是考虑到派生类的需要,在基类中预留了一个函数名。例如:一个表示封闭图形的基类A,在基类A中求面积是无意义的,因为不知道它是什么封闭图形,但是可以将求面积的函数定义为虚函数,各派生类根据所表示的图形的不同重写这个虚函数。由此引出纯虚函数,即在基类中不给出函数实现的虚函数。
纯虚函数是在声明虚函数时被初始化为“0”的函数。声明纯虚函数的一般形式如下:
virtual 函数类型 函数名(参数表)=0; 它后面的0并不表示函数的返回值为0,只是告诉编译系统“这是纯虚函数”,没有函数的功能,不能被调用。
1)抽象类:
如果一个类中至少有一个纯虚函数,那么就称该类为抽象类。
特点:
1.抽象类中至少包含一个没有定义功能的纯虚函数。
2.不允许从具体类派生出抽象类
3.抽象类不能用作函数的参数类型,函数的返回类型和显示转换的类型。
4.可以声明指向抽象类的指针或引用,此指针可以指向它的派生类,进而实现多态性。
4.如果派生类重没有定义虚函数的额实现,而派生类知识继承基类的纯虚函数,则这个派生类仍然是一个抽象类。