上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
1.6.1 继承提供抽象
让我们探索一下面向对象术语中最长的一个单词多态(Polymorphism),它是调用同一个方法时根据子类的不同实现而有不同表现的能力。我们已经在前面描述的棋子系统(图1.10)中见过了。如果我们的设计继续深入,可能会发现Board对象可以从玩家那里接收移动指令并调用棋子的move方法。Board不需要知道棋子的类型,只需调用其move方法,相应的棋子子类将会知道如何移动,比如使用马(Knight)的移动方法或者兵(Pawn)的移动方法。
多态是一个非常酷的概念,但在Python编程中是一个很少出现的单词。Python使用另一种方法让子类看起来像父类。用Python实现的棋盘对象可以接收任何拥有move方法的对象,不管它是棋子象、汽车还是鸭子。当move方法被调用时,棋子象(Bishop)会在棋盘上移动,汽车会驶向某处,鸭子则会看心情游走或飞走。
Python中的这种多态通常被称为鸭子类型[6]:如果它走路像鸭子,游泳像鸭子,那么它就是鸭子。我们不关心它是否真的是一只鸭子(继承自鸭子类),只要它可以像鸭子一样会游泳或走路即可。鹅和天鹅就很容易提供这种像鸭子的行为。以鸟类设计为例,鸭子类型允许将来的设计者方便地创建新的鸟类,而不用为所有可能种类的水鸟指定正式的继承层级。在上面的棋子示例中,我们用正规的继承关系涵盖了所有可能的棋子类型。鸭子类型也允许程序员扩展原有的设计,加入一些原来的设计者完全没有考虑的行为。比如,将来的设计者可以创建一个会游泳、会走路的企鹅,它可以使用同样的鸭子接口但不需要继承自鸭子父类。