多态是面向对象的又一重要概念,字面意义就是“多种状态”。在程序中不需要区分引用对象,用相同的调用方法,完成引用对象的功能而表现出多种状态。有了多态,就不需要为每个具体的子类编写功能调用,是一种泛型编程。如果你是一个公司的后勤经理,需要打扫地面,不论是扫地机器人还是清洁工,你只要告诉他打扫的范围,他们就可以完成打扫的任务。
在一些语言中需要使用继承、接口、不同参数方法来实现多态。由于Python是动态语言,其实现的基本方式称为“鸭子类型”(duck typing)。即"当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。"在Python的调用语义中,只要调用对象具有所调用的属性,那么不管调用对象是什么类型,就可以调用成功。
在维基百科的词条(https://en.wikipedia.org/wiki/Duck_typing)中示例代码如下:
class Duck:
def fly(self):
print("Duck flying")
class Airplane:
def fly(self):
print("Airplane flying")
class Whale:
def swim(self):
print("Whale swimming")
def lift_off(entity):
entity.fly()
duck = Duck()
airplane = Airplane()
whale = Whale()
lift_off(duck) # prints `Duck flying`
lift_off(airplane) # prints `Airplane flying`
lift_off(whale) # Throws the error `'Whale' object has no attribute 'fly'`
在函数lift_off()中对传入的entity调用了fly()方法,传入函数的是什么对象类型,只要entity引用的对象包括fly()方法,就可以成功调用,如lift_off(duck)、lift_off(airplane)。而第三次调用时,即lift_off(whale),传入的是Whale类的实例,其不具有fly()属性,因此调用就会失败。
正是因为Python的这种特性,降低了Python实现多态的难度,提高了多态实现的灵活性。所以在一些Python的面向对象程序资料中,对多态的介绍仅限于此。