Python中方法重载和方法覆盖的区别


在Python的面向对象编程(OOP)中,方法非常重要。它们对于隔离类中的功能以及赋予对象执行特定任务的能力至关重要。但是,两个OOP概念——**方法重载**和**方法覆盖**——有时会造成混淆。本文将讨论这两个概念之间的区别及其在Python中的应用。

语法

在Python中定义方法需要使用“def”关键字,方法名,参数和方法体。

def method_name(parameter1, parameter2, ...):
   # method body
   return value

比较表

方法重载

方法覆盖

指定义多个具有相同名称但参数不同的方法

指在子类中定义一个与超类中方法同名的方法

在Python中可以使用默认参数实现

可以通过在子类中定义与超类中同名的方法来实现

允许一个类具有多个同名但根据输入参数具有不同行为的方法

允许子类提供其自身对超类中定义的方法的实现

调用哪个方法的选择是在编译时根据传递给方法的参数数量和类型确定的

调用哪个方法的选择是在运行时根据实际引用的对象确定的

Python原生不支持

Python原生支持

示例

示例1:方法重载

方法重载是指定义多个具有相同名称但参数类型或参数数量不同的方法。在Python中,方法重载是使用默认参数实现的。

class MyClass:
   def my_method(self, arg1, arg2=None):
      if arg2:
         print(arg1 + arg2)
      else:
         print(arg1)

# Calling the method with one argument
obj = MyClass()
obj.my_method(10)

# Calling the method with two arguments
obj.my_method(10, 20) 

输出

10
30

在这个例子中,我们定义了一个名为“my_method”的方法,它接受两个参数,第二个参数是可选的。如果存在第二个参数,该方法将添加这两个参数;否则,将打印第一个参数。

示例2:方法覆盖

另一方面,方法覆盖是指在子类中定义一个与超类中同名的方法。然后,子类方法将覆盖超类方法。

class Animal:
   def speak(self):
      print("Animal Speaking!")
class Dog(Animal):
   def speak(self):
      print("Dog barking!")
obj = Dog()
obj.speak()

输出

Dog barking!

如上所示,我们有一个“Dog”子类和一个“Animal”超类。“Animal”类的“speak”方法被“Dog”类的“speak”方法覆盖。现在,让我们来看一个包含方法重载和方法覆盖的完整的Python代码块:

class Parent:
   def my_method(self, arg1, arg2):
      print("Parent my_method")
class Child(Parent):
   def my_method(self, arg1):
      print("Child my_method")
obj = Child()
obj.my_method("Hello") 

输出

Child my_method

在本例中,我们也有一个名为“Parent”的超类和一个名为“Child”的子类。“Child”类有一个名为“my_method”的方法,它只接受一个参数,而“Parent”类的“my_method”方法接受两个参数。当在“Child”类实例上调用时,只接受一个参数的“my_method”方法将被调用。

示例

class Shape:
   def area(self):
      pass
class Rectangle(Shape):
   def __init__(self, length, breadth):
      self.length = length
      self.breadth = breadth
   def area(self):
      return self.length * self.breadth
class Circle(Shape):
   def __init__(self, radius):
      self.radius = radius
   def area(self):
      return 3.14 * self.radius * self.radius
   def area(self, diameter):
      self.radius = diameter / 2
      return 3.14 * self.radius * self.radius
r = Rectangle(5, 10)
print("Area of rectangle:", r.area())
c = Circle(7)
print("Area of circle with radius 7:", c.area())
print("Area of circle with diameter 10:", c.area(10)) 

输出

Area of rectangle: 50
Area of circle with radius 7: 153.86
Area of circle with diameter 10: 78.5

这里,“Circle”和“Rectangle”都修改了基本“Shape”类的`area()`方法。“Circle”类覆盖了`area()`方法来计算指定半径的圆的面积,“Rectangle”类定义了自己的`area()`方法版本来计算矩形的面积。“Circle”类还通过添加第二个`area()`函数来计算指定直径的圆的面积来演示方法重载。在这个例子中,我们也有超类“Father”和子类“Child”。“Parent”类的“my_method”方法接受两个参数,而“Child”类的方法只接受一个参数。

当创建一个“Rectangle”类的实例并使用其`area()`方法时,矩形的面积为50平方英尺。当我们使用半径为7的实例时,“Circle”类的`area()`方法返回圆的面积,大约为153.86。最后,我们使用直径为10的圆,并调用“Circle”类的`area()`方法来查找圆的面积,大约为78.5。

结论

在探索面向对象编程的世界时,理解方法重载和方法调用之间的细微差别至关重要。这两个概念经常被混淆,这可能会导致未来的问题和不确定性。方法重载是指定义多个具有相同名称但参数不同的方法的技术。这与方法覆盖形成对比,方法覆盖是在子类中创建与超类中同名的方法。要在Python中覆盖方法,必须提供与超类中同名的方法。默认参数通常被用作解决方法重载的办法。

更新于:2023年4月18日

8000+浏览量

启动你的职业生涯

通过完成课程获得认证

开始学习
广告