Python 简明教程

Python - Polymorphism

What is Polymorphism in Python?

术语 polymorphism 指的是在不同上下文中采用不同形式的函数或方法。由于 Python 是动态类型语言,因此 Python 中的多态性很容易实现。

如果某个父类中的方法在它的不同子类中由不同的业务逻辑覆盖,则这个基类方法就是一个多态方法。

Ways of implementing Polymorphism in Python

有四种方法可以在 Python 中实现多态性 −

  1. Duck Typing

  2. Operator Overloading

  3. Method Overriding

  4. Method Overloading

ways to implement polymorphism

Duck Typing in Python

鸭子类型是一种概念,其中对象类型或类不如它定义的方法重要。使用此概念,只要该方法存在,就可以在对象上调用任何方法,而无需检查其类型。

这个术语由一句很有名的引用来定义,叫做:假设有一只鸟像鸭子一样走路,像鸭子一样游泳,看起来像鸭子,并且嘎嘎叫,那么它很可能是一只鸭子。

Example

在下面给出的代码中,我们实际展示了鸭子类型的概念。

class Duck:
   def sound(self):
      return "Quack, quack!"

class AnotherBird:
   def sound(self):
      return "I'm similar to a duck!"

def makeSound(duck):
   print(duck.sound())

# creating instances
duck = Duck()
anotherBird = AnotherBird()
# calling methods
makeSound(duck)
makeSound(anotherBird)

执行此代码时,将生成以下输出 −

Quack, quack!
I'm similar to a duck!

Method Overriding in Python

在方法重写中,在子类中定义的方法具有与其超类中的方法相同的名字,但实现了不同的功能。

Example

作为下面给出的多态性示例,我们有 shape ,它是一个抽象类。它被两个类 circle 和 rectangle 用作父类。这两个类以不同的方式重写了父级的 draw() 方法。

from abc import ABC, abstractmethod
class shape(ABC):
   @abstractmethod
   def draw(self):
      "Abstract method"
      return

class circle(shape):
   def draw(self):
      super().draw()
      print ("Draw a circle")
      return

class rectangle(shape):
   def draw(self):
      super().draw()
      print ("Draw a rectangle")
      return

shapes = [circle(), rectangle()]
for shp in shapes:
   shp.draw()

Output

当运行以上代码时,它会产生以下输出 −

Draw a circle
Draw a rectangle

变量 shp 首先引用 circle 对象,并从 circle 类中调用 draw() 方法。在下一次迭代中,它引用 rectangle 对象,并从 rectangle 类中调用 draw() 方法。因此 shape 类中的 draw() 方法是多态的。

Overloading Operators in Python

假设你创建了一个表示二维向量的 Vector 类,当你使用加号运算符给它们相加时会发生什么?Python 很可能会向你大喊大叫。

但是,您可以在自己的类中定义 add 方法来执行向量加法,然后加法运算符将按预期的那样执行 −

Example

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)

   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

执行上述代码后,将生成以下结果 −

Vector(7,8)

Method Overloading in Python

当一个类包含两个或更多具有相同名称但不同参数数量的方法时,这种情况下可以称为方法重载。

默认情况下,Python 不允许方法重载,但是我们可以使用可变长参数列表、多重派发和默认参数等技术来实现这一目标。

Example

在下面的示例中,我们使用可变长参数列表来实现方法重载。

def add(*nums):
   return sum(nums)

# Call the function with different number of parameters
result1 = add(10, 25)
result2 = add(10, 25, 35)

print(result1)
print(result2)

执行上述代码后,将生成以下结果 −

35
70