多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数(Virtual Function) 实现的。
多态指同一个实体同时具有多种形式。它是面向对象程序设计(OOD)的一个重要特征。如果一个语言只支持类而不支多态,只能说明它是基于对象的,而不是面向对象的。C++中的多态性具体体现在运行和编译两个方面。运行时多态是动态多态,其具体引用的对象在运行时才能确定。编译时多态是静态多态,在编译时就可以确定对象使用的形式。
多态可分为: 1.编译多态:主要是体现在重载,系统在编译时就能确定调用重载函数的哪个版本。 2.运行多态:主要体现在OO设计的继承性上,子类的对象也是父类的对象,即上溯造型,所以子类对象可以作为父类对象使用,父类的对象变量可以指向子类对象。因此通过一个父类发出的方法调用可能执行的是方法在父类中的实现,也可能是某个子类中的实现,它是由运行时刻具体的对象类型决定的。
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
覆盖:
在基类中定义了一个非虚拟函数,然后在派生类中又定义了一个同名同参数同返回类型的函数,这就是覆盖了。
在派生类对象上直接调用这个函数名,只会调用派生类中的那个。
//coverage.cpp
#include <iostream>
using namespace std;
class A
{
public:
void ShowMessage();
};
class B:public A
{
public:
void ShowMessage();
};
void A::ShowMessage()
{
cout<<"Hello,This is A./n";
return;
}
void B::ShowMessage()
{
cout<<"Hello,This is B./n";
return;
}
int main()
{
A* p;
B memb;
*p = memb;
p->ShowMessage();
memb.ShowMessage();
return 0;
}
输出为:
Hello,This is A.
Hello,This is B.
重载:
有两个或多个函数名相同的函数,但是函数的形参列表不同。在调用相同函数名的函数时,根据形参列表确定到底该调用哪一个函数。
//reload
#include <iostream>
using namespace std;
class A
{
public:
void ShowMessage();
void ShowMessage(string str);
};
void A::ShowMessage()
{
cout<<"Hi,This is A./n";
return;
}
void A::ShowMessage(string str)
{
cout<<str<<endl;
return;
}
int main()
{
A mem;
mem.ShowMessage();
mem.ShowMessage("Hello.How are you?/n");
return 0;
}
输出为:
Hi,This is A.
Hello.How are you?
多态:
在基类中定义了一个虚拟函数,然后在派生类中又定义一个同名,同参数表的函数,这就是多态。多态是这3种情况中唯一采用动态绑定技术的一种情况。也就是说,通过一个基类指针来操作对象,如果对象是基类对象,就会调用基类中的那个函数,如果对象实际是派生类对象,就会调用派声雷中的那个函数,调用哪个函数并不由函数的参数表决定,而是由函数的实际类型决定。
//poly.cpp
#include <iostream>
using namespace std;
class A
{
public:
virtual void ShowMessage();
};
class B:public A
{
public:
void ShowMessage();
};
void A::ShowMessage()
{
cout<<"This is A./n";
return;
}
void B::ShowMessage()
{
cout<<"This is B./n";
return;
}
int main()
{
A* p;
p=new A();
p->ShowMessage();
p=new B();
p->ShowMessage();
return 0;
}
输出为:
This is A.
This is B.