在 Python 的面向对象编程中,函数重写(Method Overriding)是一个重要的特性。通过重写父类的方法,子类可以提供特定的实现,从而实现多态和灵活的代码设计。本文将通过一个父类和子类的示例,汇总 Python 中常见的函数重写方法,包括构造方法、字符串表示、比较、迭代、索引访问等。
示例:常见的函数重写方法
1. __init__
方法
- 目的:构造方法,用于初始化对象的属性。
- 重写:子类可以重写父类的
__init__
方法,以添加额外的初始化逻辑。
2. speak
方法
- 目的:定义动物发出的声音。
- 重写:子类可以提供特定的实现,比如
Dog
类的speak
方法返回 “Woof!”。
3. __str__
方法
- 目的:返回对象的用户友好字符串表示。
- 重写:子类可以提供更具体的描述,例如返回狗的名字和品种。
4. __repr__
方法
- 目的:返回对象的官方字符串表示,通常用于调试。
- 重写:子类可以提供更详细的信息,以便在调试时使用。
5. __len__
方法
- 目的:定义对象的长度。
- 重写:子类可以返回特定的长度计算,例如返回狗的名字和品种的总长度。
6. __add__
方法
- 目的:定义对象的加法操作。
- 重写:子类可以实现自定义的加法行为,例如将两个狗的名字结合在一起。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
def __str__(self):
return f"Animal: {self.name}"
def __repr__(self):
return f"Animal(name='{self.name}')"
def __len__(self):
return len(self.name)
def __add__(self, other):
return Animal(self.name + " & " + other.name)
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 调用父类的构造方法
self.breed = breed
def speak(self): # 重写父类的 speak 方法
return "Woof!"
def __str__(self): # 重写父类的 __str__ 方法
return f"Dog: {self.name}, Breed: {self.breed}"
def __repr__(self): # 重写父类的 __repr__ 方法
return f"Dog(name='{self.name}', breed='{self.breed}')"
def __len__(self): # 重写父类的 __len__ 方法
return len(self.name) + len(self.breed) # 返回名字和品种的总长度
def __add__(self, other): # 重写父类的 __add__ 方法
return Dog(self.name + " & " + other.name, self.breed)
# 示例使用
dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Max", "Bulldog")
# 调用重写的方法
print(dog1.speak()) # 输出: Woof!
print(dog2.speak()) # 输出: Woof!
# 使用 __str__ 和 __repr__
print(dog1) # 输出: Dog: Buddy, Breed: Golden Retriever
print(repr(dog1)) # 输出: Dog(name='Buddy', breed='Golden Retriever')
# 使用 __len__
print(len(dog1)) # 输出: 22 (5 + 18)
# 使用 __add__
combined_dog = dog1 + dog2
print(combined_dog) # 输出: Dog: Buddy & Max, Breed: Golden Retriever
print(repr(combined_dog)) # 输出: Dog(name='Buddy & Max', breed='Golden Retriever')
7. __getitem__
方法
- 目的:定义使用索引访问对象的行为。
- 重写:可以让自定义类支持索引访问。
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3])
print(my_list[1]) # 输出: 2
8. __setitem__
方法
- 目的:定义使用索引设置对象的行为。
- 重写:可以让自定义类支持索引赋值。
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
my_list = MyList([1, 2, 3])
my_list[1] = 10
print(my_list.items) # 输出: [1, 10, 3]
9. __delitem__
方法
- 目的:定义使用索引删除对象的行为。
- 重写:可以让自定义类支持索引删除。
class MyList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
del self.items[index]
my_list = MyList([1, 2, 3])
del my_list[1]
print(my_list.items) # 输出: [1, 3]
10. __iter__
方法
- 目的:定义对象的迭代行为,使得对象可以被迭代(例如,使用
for
循环)。 - 重写:当使用
for
循环或list()
函数等需要迭代的上下文时,Python 会调用这个方法。
class MyCollection:
def __init__(self, items):
self.items = items
def __iter__(self):
return iter(self.items) # 返回一个迭代器
my_collection = MyCollection([1, 2, 3, 4, 5])
for item in my_collection:
print(item) # 输出: 1, 2, 3, 4, 5
11. __contains__
方法
- 目的:定义使用
in
运算符检查对象是否包含某个元素的行为。 - 重写:当使用
in
关键字检查对象的成员时,Python 会调用这个方法。
class MyCollection:
def __init__(self, items):
self.items = items
def __contains__(self, item):
return item in self.items # 检查元素是否在集合中
my_collection = MyCollection([1, 2, 3, 4, 5])
print(3 in my_collection) # 输出: True
print(6 in my_collection) # 输出: False
12. __call__
方法
- 目的:使对象可调用,就像函数一样。
- 重写:当对象被调用时,Python 会调用这个方法。
class Adder:
def __init__(self, x):
self.x = x
def __call__(self, y):
return self.x + y # 返回 x 和 y 的和
# 使用示例
add_five = Adder(5)
print(add_five(10)) # 输出: 15
总结
在 Python 中,函数重写是面向对象编程的核心特性之一。通过重写父类的方法,子类可以提供特定的实现,从而实现多态和灵活的代码设计。常见的重写方法包括 __init__
、speak
、__str__
、__repr__
、__len__
、__add__
、__getitem__
、__setitem__
、__delitem__
、__iter__
、__contains__
和 __call__
等。这些方法使得 Python 的对象更加灵活和强大,能够适应不同的需求和场景。通过合理使用函数重写,您可以编写出更具可读性和可维护性的代码。