要说 Python 里的重载,那可不像 C++ 或者 Java 那么直白。Python 里的“重载”其实包含了两种概念:方法重写(Method Overriding)和运算符重载(Operator Overloading)。你要是搞混了,可就麻烦了。
方法重写:子类改造父类的方法
先说方法重写。这东西其实挺好理解,就是子类继承父类,但是觉得父类的方法不太符合自己的需求,于是就自己重新定义一个同名的方法。这就是方法重写,也叫override。
举个例子,咱们来个“动物”类:
“`python
class Animal:
def speak(self):
print(“动物叫”)
class Dog(Animal):
def speak(self):
print(“汪汪汪”)
class Cat(Animal):
def speak(self):
print(“喵喵喵”)
animal = Animal()
dog = Dog()
cat = Cat()
animal.speak() # 输出: 动物叫
dog.speak() # 输出: 汪汪汪
cat.speak() # 输出: 喵喵喵
“`
你看,Dog
和 Cat
都继承了 Animal
,但是它们都重写了 speak
方法,所以调用的时候,输出的内容就不一样了。这不是很简单吗?这就是方法重写,核心在于子类重新定义了父类中已有的方法,并且方法名、参数列表都一样。
但是!注意啊,Python 里没有像 Java 或者 C++ 那种严格意义上的方法重载(overload),也就是靠参数列表不同来区分同名方法。Python 里,如果在一个类里定义了多个同名方法,只会保留最后一个,前面的会被覆盖掉。记住这点,很重要!
运算符重载:让你的类也能玩转+-*/
接下来是运算符重载。这东西听起来好像很高大上,其实也没那么复杂。就是让你的自定义类也能像内置类型一样使用 +
、-
、*
、/
这些运算符。
想想,如果两个向量相加,你希望直接用 +
号,而不是写一个 add_vectors
函数,是不是更方便?运算符重载就是干这个的。
Python 提供了很多特殊的“魔术方法”(Magic Methods),以双下划线开头和结尾,比如 __add__
、__sub__
、__mul__
、__div__
等等。你只需要在你的类里定义这些方法,就可以重载对应的运算符。
举个例子,咱们来个“向量”类:
“`python
class Vector:
def init(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __str__(self):
return f"({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3) # 输出: (4, 6)
“`
看到没?我们定义了 __add__
方法,这样就可以直接用 +
号来相加两个 Vector
对象了。这个 __add__
方法接收两个参数,self
指的是第一个操作数,other
指的是第二个操作数。返回一个新的 Vector
对象,表示两个向量的和。
同理,你可以定义 __sub__
来重载减法,__mul__
来重载乘法,等等。
再举个例子,重载乘法:
“`python
class Vector:
def init(self, x, y):
self.x = x
self.y = y
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __str__(self):
return f"({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = v1 * 3
print(v2) # 输出 (3, 6)
“`
这里,__mul__
方法接收一个标量 scalar
,返回一个新的 Vector
对象,表示向量乘以标量。
运算符重载确实能让你的代码更简洁易懂,但是也要适度使用。如果过度使用,反而会让代码变得难以理解。一定要确保重载后的运算符的行为符合用户的预期,别搞出什么幺蛾子。
还有一点,运算符重载不只是针对数值运算。你还可以重载比较运算符,比如 __eq__
(等于), __ne__
(不等于), __lt__
(小于), __gt__
(大于), __le__
(小于等于), __ge__
(大于等于)。这样你就可以直接用 ==
、!=
、<
、>
这些符号来比较你的自定义对象了。
例如:
“`python
class Point:
def init(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(3, 4)
print(p1 == p2) # 输出: True
print(p1 == p3) # 输出: False
“`
总而言之,Python 的“重载”其实是方法重写和运算符重载的结合。方法重写是子类对父类方法的改造,运算符重载是让你的自定义类也能玩转各种运算符。 掌握了这些,你就能写出更优雅、更 Pythonic 的代码啦! 不过,用的时候也要谨慎,别过度使用,适得其反。
评论(0)