杰瑞科技汇

Python 3重写时需注意哪些关键点?

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

Python 3重写时需注意哪些关键点?-图1
(图片来源网络,侵删)

什么是方法重写?

方法重写指的是在子类中,定义一个与父类中具有相同名称相同参数列表的方法。

当子类对象调用这个被重写的方法时,Python 会执行子类中定义的版本,而不是父类中的版本,这允许子类继承父类的功能,并根据自身的需求对其进行修改或扩展。

核心目的:

  • 实现多态:不同的对象对同一个消息(方法调用)可以有不同的响应。
  • 定制化行为:让子类拥有自己特有的功能,而无需修改父类的代码。

简单的例子

让我们通过一个经典的动物例子来理解。

Python 3重写时需注意哪些关键点?-图2
(图片来源网络,侵删)

步骤 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: 定义子类并重写方法

我们创建 DogCat 这两个子类,它们都继承自 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()         # 调用继承的方法,输出: 咪咪 正在吃东西。

输出结果:

Python 3重写时需注意哪些关键点?-图3
(图片来源网络,侵删)
一只普通的动物 发出了一些声音。
一只普通的动物 正在吃东西。
--------------------
大黄 汪汪叫!
大黄 正在吃东西。
--------------------
咪咪 喵喵叫!
咪咪 正在吃东西。

从结果可以看出,my_dogmy_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。

在这个例子中,ElectricCardescribe 方法没有完全抛弃 Cardescribe,而是通过 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 中的“重写”概念!如果你有更具体的问题,随时可以提出。

分享:
扫描分享到社交APP
上一篇
下一篇