多态
1什么是多态?
1.1概念
多态的概念众说纷纭,下面是几种代表性的说法:
“This ability to manipulate more than one type with a pointer or a reference to a base classis spoken of as polymorphism” (《C++ Primer》第838页)。即用基类的指针/引用来操作多种类(基类和其派生类)的对象的能力称之为多态。它是从语言实现的角度来考虑的。
“polymorphism provides another dimension of separation of interface from implementation, to decouple what from how”(《Think in Java》3rd edtion),即多态提供了另外一种分离接口和实现(即把“做什么”与“怎么做”分开)的一种尺度。它是从设计的角度考虑的。
“The ability to use the same expression to denote different operations is refered to as Polymorphism”,(《Object-Oriented Methods Principles & Practice》3rd Edition,第16页)。简单的说,多态就是“相同的表达式,不同的操作”,也可以说成“相同的命令,不同的操作”。这是从面向对象的语义的角度来看的。
三种说法分别从不同的角度来阐述了多态的实质。其中第三种说法尤为确切,下面着重分析第三种说法。
先解释这句话的含义:
相同的表达式—函数调用
不同的操作 —根据不同的对象就有不同的操作。
举个例子来说明,比如在公司中有各种职责不同的员工(程序员,业务员,文管等),他们“上班”时,做不同的事情(也可以看作是一种业务逻辑),我们把他们各自的工作都抽象为"上班",关系如下:
员工
/ | \ ——继承关系
程序员业务员文管
每天上班时间一到,相当于发了一条这样的命令:
“员工们.开始上班”(同一条表达式)
每个员工接到这条命令(同样的命令)后,就“开始上班”,但是他们做的是各自的工作,程序员就开始“Coding”,业务员就开始“联系业务”,文管员就开始“整理文档”。即“相同的表达式(函数调用),(在运行期根据不同的对象来执行)不同的操作
下面我们来用Delphi实现这个实例


Type
Employee=Class(Tobject)//员工基类
public
procedure Work;Virtual;abstract;//开始工作的过程
end;
Programmor=Class(Employee)//程序员类--继承自员工类
public
procedure Work;override;//程序员的工作过程
end;
BusinessMan=Class(Employee)//业务员类--继承自员工类
public
procedure Work;override;//业务员的工作过程
end;
DocManager=Class(Employee)//文档管理员类-----继承自员工类
public
procedure Work;override;//文档管理员的工作过程
end;
procedure Programmor.Work;//程序员的具体工作过程实现
begin
Showmessage('程序开始Coding');
end;
procedure BusinessMan.Work;//业务员的具体工作过程实现
begin
Showmessage('业务员开始联系业务');
end;
procedure DocManager.Work;//文档管理员的具体工作过程实现
begin
Showmessage('文档管理员开始整理文档');
end;
//上班了,各位员工开始工作
procedure TForm1.btn2Click(Sender: TObject);
const
Num=3;
var
emp:arrayof Employee;
i:Integer;
begin
//实现多态
setLength(emp,Num);
emp[0]:=Programmor.Create;
emp[1]:=BusinessMan.Create;
emp[2]:=DocManager.Create;
for i:=0to length(emp)-1do
emp[i].Work;//分别调用各员工的具体的工作过程
end;
1.2多态的意义
封装和继承的意义是它们实现了代码重用,而多态的意义在于,它实现了接口重用(同一的表达式),接口重用带来的好处是程序更易于扩展,代码重用更加方便,更具有灵活性,也就能真实地反映现实世界。
比如为了更好地管理,把程序员分为C++程序员,Delphi程序员。…
员工
/ | \ ——继承关系
程序员业务员文管
/ \ ——继承关系
C++程序员 Delphi程序员
代码如下:

View Code
Type
CppProgarmmer=class(Progarmmer)//c++程序员,继承自程序员类
public
procedure Work;override;//c++程序员的工作过程
end;
DelphiProgarmmer=class(Progarmmer)//delphi程序员,继承自程序员类
public
procedure Work;override;//delphi程序员的工作过程
end;
procedure CppProgarmmer.Work;
begin
Showmessage('C++ 程序员开始高度Bug!');
end;
procedure DelphiProgarmmer.Work;
begin
Showmessage('Delphi 程序员开始Coding!');
end;
//现在重新调用
//上班了,各位员工开始工作
procedure TForm1.btn2Click(Sender: TObject);
const
Num=5;
var
emp:arrayof Employee;
i:Integer;
begin
//实现多态
setLength(emp,Num);
emp[0]:=Programmor.Create;
emp[1]:=BusinessMan.Create;
emp[2]:=DocManager.Create;
emp[3]:=CppProgarmmer.Create;
emp[4]:=DelphiProgarmmer.Create;
for i:=0to length(emp)-1do
emp[i].Work;//分别调用各员工的具体的工作过程
end;