文章目录
- 1. 继承
- 1.1 为什么要用继承
- 1.2 继承的基本语法
- 1.3 方法重写
- 1.4 多重继承
- 2. supper()
- 2.1 作用
- 2.2 基本语法
- 2.3 注意事项
- 2.4 super() 在多继承中的特点
1. 继承
在 Python 里,继承是一种强大的编程概念,它允许一个类(子类)去继承另一个类(父类)的属性和方法。就好比孩子会继承父母的一些特征和能力一样
1.1 为什么要用继承
继承的好处在于代码复用和构建清晰的类层次结构。
借助继承,无需在每个类里重复编写相同的代码,只要把通用的属性和方法放在父类中,子类就能直接使用。
1.2 继承的基本语法
以下是 Python 中实现继承的简单示例
# 定义一个父类
class Animal:def __init__(self, name):self.name = namedef speak(self):print(f"{self.name} 发出了声音。")# 定义一个子类,继承自 Animal 类
class Dog(Animal):def bark(self):print(f"{self.name} 汪汪叫。")# 创建一个 Dog 类的实例
dog = Dog("旺财")# 调用从父类继承的方法
dog.speak()
# 调用子类自己的方法
dog.bark()
在这个例子中,Animal 是父类,Dog 是子类。
Dog 类通过 class Dog(Animal) 语句继承了 Animal 类。这意味着 Dog 类可以使用 Animal 类中定义的属性和方法,像 init 方法和 speak 方法。
同时,Dog 类还能有自己独特的方法,例如 bark 方法。
1.3 方法重写
子类可以对从父类继承的方法进行重写,也就是在子类里重新定义这个方法,让它有不同的行为。
下面是一个方法重写的示例:
class Animal:def speak(self):print("动物发出了声音。")class Cat(Animal):def speak(self):print("猫咪喵喵叫。")cat = Cat()
cat.speak()
在这个例子中,Cat 类重写了 Animal 类的 speak 方法,当调用 cat.speak() 时,会执行 Cat 类中定义的 speak 方法,输出 “猫咪喵喵叫。
1.4 多重继承
Python 还支持多重继承,也就是一个子类可以继承多个父类。
以下是多重继承的示例:
class A:def method_a(self):print("方法 A")class B:def method_b(self):print("方法 B")class C(A, B):passc = C()
c.method_a()
c.method_b()
在这个例子中,C 类继承了 A 类和 B 类,所以 C 类的实例可以调用 A 类和 B 类中定义的方法。
通过继承,你能够构建出复杂而灵活的类层次结构,让代码更加简洁、易于维护。
2. supper()
在 Python 里,super() 是一个非常实用的内置函数,主要用于在子类中调用父类的方法
2.1 作用
super() 函数能让子类在重写父类方法时,还可以调用父类的同名方法,这样就避免了代码重复,并且保证了类的层次结构和继承关系的正确性。
2.2 基本语法
在 Python 3 中,super() 函数的基本语法很简单,无需传递参数,通常的使用方式如下:
super().父类方法名(参数)
- 调用父类的构造方法
在子类的构造方法中,常常需要调用父类的构造方法来初始化一些父类的属性。
以下是一个示例:
class Animal:def __init__(self, name):self.name = nameclass Dog(Animal):def __init__(self, name, breed):super().__init__(name)self.breed = breeddog = Dog("旺财", "金毛")
print(f"狗狗的名字是 {dog.name},品种是 {dog.breed}。")
在这个例子中,Dog 类的 init 方法通过 super().init(name) 调用了父类 Animal 的构造方法,完成了 name 属性的初始化。
- 调用父类的其它方法
当子类重写了父类的某个方法,但还需要使用父类该方法的功能时,可以用 super() 来调用。
示例如下:
class Animal:def speak(self):print("动物发出了声音。")class Cat(Animal):def speak(self):super().speak()print("猫咪喵喵叫。")cat = Cat()
cat.speak()
在这个例子中,Cat 类重写了 speak 方法,通过 super().speak() 调用了父类 Animal 的 speak 方法,然后再添加了自己独特的输出。
2.3 注意事项
- super() 函数返回的是一个代理对象,它会按照方法解析顺序(MRO)来查找并调用父类的方法。可以使用 类名.mro 查看具体的 MRO 顺序。
- 在多继承的情况下,super() 的调用逻辑会更复杂,要确保理解 MRO 顺序,避免出现意外的结果。
通过使用 super() 函数,可以更方便地管理类的继承关系,提高代码的复用性和可维护性。
2.4 super() 在多继承中的特点
在多继承场景下,super() 函数有着独特的特点和行为,下面从调用顺序、方法解析顺序(MRO)、参数传递和实际应用示例等方面详细介绍:
- 调用顺序与方法解析顺序(MRO)
- MRO 规则:Python 使用 C3 线性化算法来确定类的方法解析顺序(MRO)。MRO 定义了在调用 super() 时,Python 查找父类方法的顺序。可以通过 类名.mro 查看具体的 MRO 顺序。
- 特点:super() 在多继承中会按照 MRO 顺序依次调用父类的方法,而不是只调用直接父类的方法。这意味着它会沿着 MRO 链向上查找,直到找到所需的方法。
- 参数传递
在多继承里,super() 函数调用父类方法时,参数会按照 MRO 顺序依次传递。
当子类调用 super() 并传递参数时,这些参数会被传递给 MRO 链中的下一个类的相应方法。
- 实际应用示例
class A:def __init__(self):print("A 的初始化方法")class B(A):def __init__(self):print("B 的初始化方法")super().__init__()class C(A):def __init__(self):print("C 的初始化方法")super().__init__()class D(B, C):def __init__(self):print("D 的初始化方法")super().__init__()d = D()
print(D.__mro__)# 结果:
D 的初始化方法
B 的初始化方法
C 的初始化方法
A 的初始化方法
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)***Repl Closed***
在上述代码中:
- 类 D 继承自 B 和 C,而 B 和 C 又都继承自 A。
- 创建 D 类的实例 d 时,调用 D 的 init 方法。在 D 的 init 方法中使用 super().init() 会按照 MRO 顺序调用父类的 init 方法。
- 输出结果显示,调用顺序为 D -> B -> C -> A,这正是 D 类的 MRO 顺序。
- 避免重复调用
super() 能避免在多继承中对同一个父类方法的重复调用。由于它按照 MRO 顺序依次调用,每个父类方法只会被调用一次,保证了代码的正确性和效率。
- 注意事项
- 要确保在多继承中每个父类的方法都正确使用 super() 调用其父类的相应方法,否则可能会破坏 MRO 顺序,导致部分父类方法未被调用。
- 在多继承中使用 super() 时,需要对 MRO 有清晰的理解,以避免出现意外的结果。
总之,super() 在多继承中的行为由 MRO 决定,它能确保父类方法按照正确的顺序被调用,同时避免重复调用,提高代码的可维护性和复用性。