Python 方法重载和方法重写的区别
在Python的面向对象编程中,方法非常重要。它们对于将功能隔离在类中并赋予物体执行特定功能的能力至关重要。然而,两个面向对象编程的概念——方法重载和方法重写——有时会引起误解。本文将讨论这两个概念的区别以及它们在Python中的应用。
语法
使用”def”关键字,方法的名称、参数和主体都是定义Python方法所必需的。
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!
我们有一个 狗 的子类型和一个 动物 的超类,如上所示。”动物”类的”speak”方法被”狗”类的”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()方法来计算矩形的面积。通过添加一个第二个area()函数来计算具有指定直径的圆的面积,Circle类还演示了方法重载。在这种情况下,超类 Father 和子类 Child 都存在。虽然”Child”类只接受一个参数,但”Parent”类的”my method”方法可以接受两个参数。
当创建Rectangle类的实例并使用其area()方法时,矩形的面积为50平方英尺。Circle类的area()函数返回圆的面积,当使用半径为7的实例时,其值约为153.86。最后,我们使用直径为10的圆,并调用Circle类的area()函数来计算圆的面积,其值约为78.5。
结论
在探索面向对象编程的世界时,理解方法重载和方法调用之间微妙的区别是至关重要的。这两者经常被混淆,这可能会导致未来出现问题和不确定性。指定具有相同名称但不同参数的多个方法的技术被称为方法重载。这与方法重写相反,方法重写涉及在子类型中创建一个与超类中的方法同名的方法。要在Python中重写方法,必须提供一个与超类中方法同名的方法。经常使用预设数字作为函数重载的修复方法。