这是一个面向对象编程的核心概念,下面我将为你详细解释 Python 3 中的方法重写。

什么是方法重写?
方法重写指的是在子类中,定义一个与父类中具有相同名称和相同参数列表的方法。
当子类对象调用这个被重写的方法时,Python 会执行子类中定义的版本,而不是父类中的版本,这允许子类继承父类的功能,并根据自身的需求对其进行修改或扩展。
核心目的:
- 实现多态:不同的对象对同一个消息(方法调用)可以有不同的响应。
- 定制化行为:让子类拥有自己特有的功能,而无需修改父类的代码。
简单的例子
让我们通过一个经典的动物例子来理解。

步骤 1: 定义父类 Animal
我们创建一个 Animal 类,它有一个 make_sound 方法。
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
"""这是一个通用方法,描述动物会发出声音"""
print(f"{self.name} 发出了一些声音。")
def eat(self):
"""一个子类可能会继承的方法"""
print(f"{self.name} 正在吃东西。")
步骤 2: 定义子类并重写方法
我们创建 Dog 和 Cat 这两个子类,它们都继承自 Animal,但它们发出的声音和通用声音不同,所以我们需要重写 make_sound 方法。
# Dog 类继承自 Animal
class Dog(Animal):
def make_sound(self):
"""重写父类的 make_sound 方法"""
print(f"{self.name} 汪汪叫!")
# Cat 类继承自 Animal
class Cat(Animal):
def make_sound(self):
"""重写父类的 make_sound 方法"""
print(f"{self.name} 喵喵叫!")
步骤 3: 使用重写的方法
现在我们来创建对象并调用方法,看看会发生什么。
# 创建 Animal 对象
generic_animal = Animal("一只普通的动物")
generic_animal.make_sound() # 输出: 一只普通的动物 发出了一些声音。
generic_animal.eat() # 输出: 一只普通的动物 正在吃东西。
print("-" * 20)
# 创建 Dog 对象
my_dog = Dog("大黄")
my_dog.make_sound() # 调用被重写的方法,输出: 大黄 汪汪叫!
my_dog.eat() # 调用继承的方法,输出: 大黄 正在吃东西。
print("-" * 20)
# 创建 Cat 对象
my_cat = Cat("咪咪")
my_cat.make_sound() # 调用被重写的方法,输出: 咪咪 喵喵叫!
my_cat.eat() # 调用继承的方法,输出: 咪咪 正在吃东西。
输出结果:

一只普通的动物 发出了一些声音。
一只普通的动物 正在吃东西。
--------------------
大黄 汪汪叫!
大黄 正在吃东西。
--------------------
咪咪 喵喵叫!
咪咪 正在吃东西。
从结果可以看出,my_dog 和 my_cat 调用了它们自己类中定义的 make_sound 方法,而不是从 Animal 父类继承来的,而 eat 方法没有被重写,所以它们都使用了从父类继承来的版本。
使用 super() 调用父类方法
我们不想完全替换父类的方法,而是想在父类方法的基础上增加一些功能,这时,super() 就派上用场了。
super() 是一个内置函数,它允许你调用父类(或超类)的方法。
例子:扩展父类方法
假设我们有一个 Car 类,它有一个 describe 方法,现在我们创建一个 ElectricCar 子类,我们希望在描述中加上它是电动车的信息。
class Car:
def __init__(self, brand):
self.brand = brand
def describe(self):
return f"这是一辆 {self.brand} 牌的汽车。"
class ElectricCar(Car):
def __init__(self, brand, battery_size):
# 1. 首先调用父类的 __init__ 来初始化品牌
super().__init__(brand)
self.battery_size = battery_size # 2. 添加子类特有的属性
def describe(self):
# 1. 调用父类的 describe 方法,获取基础描述
parent_description = super().describe()
# 2. 在基础描述上添加子类特有的信息
return f"{parent_description} 它是一辆电动车,电池容量为 {self.battery_size} kWh。"
# 使用
my_tesla = ElectricCar("特斯拉", 100)
print(my_tesla.describe())
输出结果:
这是一辆 特斯拉 牌的汽车。 它是一辆电动车,电池容量为 100 kWh。
在这个例子中,ElectricCar 的 describe 方法没有完全抛弃 Car 的 describe,而是通过 super().describe() 获取了父类的返回值,然后在此基础上进行了扩展。
重写 __str__ 和 __repr__ 方法
这是方法重写的一个非常常见的应用,用于控制对象如何被“字符串化”。
__str__(self):为终端用户或普通打印提供一个“友好”的字符串表示,当你使用print(obj)或str(obj)时会调用。__repr__(self):为开发者提供一个“明确”的、官方的字符串表示,理想情况下,eval(repr(obj)) == obj应该成立,当你直接在交互式解释器中输入对象名或在调试时调用repr(obj)会触发。
例子
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
# 重写 __str__ 方法
def __str__(self):
return f"《{self.title}》 - 作者: {self.author}"
# 重写 __repr__ 方法
def __repr__(self):
return f"Book(title='{self.title}', author='{self.author}')"
# 使用
my_book = Book("Python编程:从入门到实践", "Eric Matthes")
print(my_book) # 调用 __str__
print(repr(my_book)) # 调用 __repr__
输出结果:
《Python编程:从入门到实践》 - 作者: Eric Matthes'Python编程:从入门到实践', author='Eric Matthes')
| 特性 | 描述 |
|---|---|
| 定义 | 在子类中创建一个与父类同名、同参数的方法。 |
| 目的 | 定制子类的行为,实现多态。 |
| 调用 | 当通过子类对象调用方法时,自动执行子类的版本。 |
| 扩展 | 使用 super() 关键字可以在子类方法中调用父类的同名方法,从而实现功能扩展,而不是完全替代。 |
| 常见用途 | 重写 __init__, __str__, __repr__ 等特殊方法,以自定义对象的创建和显示方式。 |
希望这个详细的解释能帮助你完全理解 Python 3 中的“重写”概念!如果你有更具体的问题,随时可以提出。
