(十)多态与鸭子类型
同一个调用表达式可以处理不同对象,由各个对象提供自己的实现。前面 book.show() 内调用 self.describe(),已经展示了这种多态。
现在把“取得书名列表”作为调用者需要的动作:
# 两个来源没有共同的自定义父类,但都提供 load()。
class MemorySource:
def load(self):
return ["Python", "NumPy"]
class FixedSource:
def load(self):
return ["Pygame"]
def show_titles(source):
for title in source.load():
print(title)
show_titles(MemorySource())
show_titles(FixedSource())输出依次是“Python”“NumPy”“Pygame”。show_titles 没有先判断类名,也没有要求来源继承某个共同基类,它直接使用需要的行为。这种按对象提供的操作协作的方式,常叫鸭子类型。
继承可以复用实现,但并不是让对象参与同一调用过程的唯一方式。对这个函数而言,需要确认的是 load() 的调用方式与返回数据能否支撑接下来的遍历;“具有同名方法”和“方法完成约定工作”也要一起核对。