前言:
面向对象的三大特性有继承、封装、多态,其中的继承和封装比较容易理解,那什么是多态呢?跟虚函数(virtual)又有什么联系?
为了写出通用的代码,做出通用的编程,以适应需求的不断变化。需要编写多种表现形态的程序,在面向对象语言中,接口的多种不同的实现方式即为多态。
那如何实现接口的不同呢?
1.重载 overload
一般是在一个类中实现若干重载的方法,这些方法的名称相同而参数形式不同。
重载需要注意:
1.位于同一个类中
2.函数的名字必须相同
3.形参列表不同
2. 覆盖(重写) override
覆盖了一个方法,以实现不同的功能。一般用于子类在继承父类时,重写父类中的方法。函数特征相同,但是具体实现不同。
重写需要注意:
1.被重写的函数不能是static的,必须是virtual的
2.重写函数必须有相同的类型,名称和参数列表
3.不在同一个类中,属于继承和派生的关系
以上两种方式都实现了接口的不同,区别在于重载 overload在编译阶段根据传入的参数来确定调用具体的函数;而覆盖(重写) override 在运行阶段,根据基类指针所指向的实例(子类),来确定来用具体哪个子类中的函数。
3.多态 Polymorphism
允许将子类类型的指针赋值给父类类型的指针,赋值之后,父类型的引用就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。
多态分为静态多态和动态多态。
静态:重载 overload
动态:覆盖(重写) override
example:
class A
{
public:
A() //构造函数
{
}
virtual void f() //虚函数,派生类可以对其进行覆盖
{
cout<<"This is A."<<endl;
}
};
class B: public A
{
public:
B()
{
}
void f() //覆盖
{
cout<<"This is B."<<endl;
}
};
int main(int argc, char *argv[])
{
A *a = new B(); //子类类型的指针赋值给父类类型的指针
a->f(); //这里的f(),所执行的是子类B中的代码,实现了多态
if(a != NULL)
delete a;
return 0;
}
结构将显示:
This is B.
以上就是覆盖父类的virtual函数,来实现的动态多态。