原文: https://pythonspot.com/polymorphism/

有时,对象有多种类型或形式。 如果我们有一个按钮,则有许多不同的绘制输出(圆形按钮,复选按钮,方形按钮,带有图像的按钮),但它们确实共享相同的逻辑:onClick()。 我们使用相同的方法访问它们。 这个想法称为多态。

多态是基于希腊语 Poly(许多)和 morphism(形式)。 我们将创建一个可以采用或使用多种形式的对象的结构。

具有函数的多态:

我们创建了两个类别:BearDog,两者都能发出不同的声音。 然后,我们创建两个实例,并使用相同的方法调用它们的动作。

  1. class Bear(object):
  2. def sound(self):
  3. print("Groarrr")
  4. class Dog(object):
  5. def sound(self):
  6. print("Woof woof!")
  7. def makeSound(animalType):
  8. animalType.sound()
  9. bearObj = Bear()
  10. dogObj = Dog()
  11. makeSound(bearObj)
  12. makeSound(dogObj)

输出:

  1. Groarrr
  2. Woof woof!

抽象类的多态(最常用)

多态 - 图1

多态可视化。

抽象结构在Document类中定义。

如果您创建编辑器,则可能事先不知道用户将打开哪种类型的文档(pdf 格式还是 word 格式?)。

像这样处理它们,而不是每个文档有 20 种类型,这不是很好吗?

  1. for document in documents:
  2. print document.name + ': ' + document.show()

为此,我们创建了一个称为document的抽象类。 此类没有任何实现,但是定义了所有形式都必须具有的结构(以函数形式)。 如果我们定义函数show(),则PdfDocumentWordDocument都必须具有show()函数。完整代码:

  1. class Document:
  2. def __init__(self, name):
  3. self.name = name
  4. def show(self):
  5. raise NotImplementedError("Subclass must implement abstract method")
  6. class Pdf(Document):
  7. def show(self):
  8. return 'Show pdf contents!'
  9. class Word(Document):
  10. def show(self):
  11. return 'Show word contents!'
  12. documents = [Pdf('Document1'),
  13. Pdf('Document2'),
  14. Word('Document3')]
  15. for document in documents:
  16. print document.name + ': ' + document.show()

输出:

  1. Document1: Show pdf contents!
  2. Document2: Show pdf contents!
  3. Document3: Show word contents!

我们有一个抽象访问点(文档),用于访问遵循相同结构的多种类型的对象(pdf,word)。

多态示例

多态 - 图2

抽象类中的结构,其他类中的实现

另一个例子是拥有一个抽象类Car,其中包含了drive()stop()结构。

我们定义了两个对象SportcarTruck,它们都是Car的一种形式。 用伪代码我们将要做的是:

  1. class Car:
  2. def drive abstract, no implementation.
  3. def stop abstract, no implementation.
  4. class Sportscar(Car):
  5. def drive: implementation of sportscar
  6. def stop: implementation of sportscar
  7. class Truck(Car):
  8. def drive: implementation of truck
  9. def stop: implementation of truck

然后,我们可以访问任何类型的汽车并调用函数,而无需进一步考虑表格是 Sportscar 还是 Truck。 完整代码:

  1. class Car:
  2. def __init__(self, name):
  3. self.name = name
  4. def drive(self):
  5. raise NotImplementedError("Subclass must implement abstract method")
  6. def stop(self):
  7. raise NotImplementedError("Subclass must implement abstract method")
  8. class Sportscar(Car):
  9. def drive(self):
  10. return 'Sportscar driving!'
  11. def stop(self):
  12. return 'Sportscar braking!'
  13. class Truck(Car):
  14. def drive(self):
  15. return 'Truck driving slowly because heavily loaded.'
  16. def stop(self):
  17. return 'Truck braking!'
  18. cars = [Truck('Bananatruck'),
  19. Truck('Orangetruck'),
  20. Sportscar('Z3')]
  21. for car in cars:
  22. print car.name + ': ' + car.drive()

输出:

  1. Bananatruck: Truck driving slowly because heavily loaded.
  2. Orangetruck: Truck driving slowly because heavily loaded.
  3. Z3: Sportscar driving!

下载练习