7.3.3 多态性

在 7.3.1 中定义的类 Student 和 Teacher 中,有一个同名的方法 getNum。虽然同名,但这 个方法在两个类中的行为是完全不同的:在 Student 中返回的是学号,而在 Teacher 中返回的 是学生人数。因此,当我们向一个对象 obj 发送 getNum 消息时,所得结果取决于 obj 的类型。 在 OOP 中,多个不同类的对象都支持相同的消息,但各对象响应消息的行为不同,这种能 力称为多态性(polymorphism),即同一操作具有不同形态的意思。

其实多态性对我们来说并非很陌生的概念。考虑表达式“a+b”,请问这个表达式执行什么操作?答案是有多种可能。如果 a、b 是数值,则该表达式执行数值加法运算;如果 a、b 是字符串,则该表达式执行字符串合并操作;如果 a、b 是两个二元组,则该表达式执行结果 是一个四元组;等等。像这样,一个操作的含义依赖于被操作的对象,就是多态性。

多态性使得我们能够刻划不同类所提供的相似方法,对使用者来说易理解、易使用,能 够减少编程错误。相反,不同类的相似方法如果定义为不同名字,对使用者来说就很不方便。 例如,在 Windows 环境下,“双击”就是一个多态操作,双击不同对象导致的行为是不同的。 双击可执行文件,能够执行程序;双击 mp3 文件,可以播放音乐;双击窗口标题栏,可以极 大化或恢复窗口大小;等等。用户如果知道“双击”大体上执行“打开”这个动作的话,那 么学习使用 Windows 时就能举一反三。

多态性的一种典型用法是,让处于同一层次的多种对象都能响应同一个消息,但导致的 行为由各对象决定。例如,如果“人”有学生、教师、官员等子类,这些子类就是处于同一 层次的,假设他们都能响应消息 getNum:学生返回自己的学号,教师返回学生人数,官员返 回工资数额。尽管对象行为各不相同,但在编程时我们可以不管这些差别,以一种统一的方 式来处理他们。假设 tom 是个学生,huck 是个教师,jerry 是个官员,则我们可能写出下列代 码来统一处理这些对象:

>>> people = [tom,huck,jerry]
>>> for p in people:
print p.getNum()