Python中继承是面向对象编程中重要的一个概念,它使子类可以继承父类的属性和方法,同时也可以在此基础上新增或者重写方法。下面将从定义、示例、多重继承、super()函数以及方法解析顺序几个方面详细介绍Python中的继承。
一、定义
继承是面向对象编程中的一种机制,它允许子类继承父类的属性和方法,同时还可以拥有自己的属性和方法。继承关系可以理解为一种"is-a"的关系。
class Parent: def __init__(self, name): self.name = name class Child(Parent): def __init__(self, name, age): super().__init__(name) self.age = age child = Child("Tom", 10) print(child.name) print(child.age)
以上代码中,Child类继承自Parent类,并且新增了一个属性age。创建Child实例时,可以调用Parent的construct方法,从而使用name属性。
二、示例
下面是一个更复杂的示例,展示了如何使用继承实现多态性。Person类和Animal类都有一个talk()方法,但是它们的表现形式是不一样的。
class Person: def __init__(self, name): self.name = name def talk(self): print(f"{self.name} is talking") class Animal: def __init__(self, name): self.name = name def talk(self): print(f"{self.name} is making sound") people = [Person("Tom"), Person("Jerry")] animals = [Animal("Cat"), Animal("Dog")] for p in people: p.talk() for a in animals: a.talk()
由于Person和Animal都有talk()方法,并且这个方法的行为是不一样的。所以我们在使用talk()方法时,可以识别并执行正确的行为。
三、多重继承
Python支持多重继承,即一个子类可以继承多个父类的属性和方法。下面的例子展示了一个拥有多重继承的类,它继承自Base1和Base2类,并且重写了greeting()方法。
class Base1: def __init__(self): self.val1 = 100 def greeting(self): print("Hello from Base1") class Base2: def __init__(self): self.val2 = 200 def greeting(self): print("Hello from Base2") class MultiDerived(Base1, Base2): def __init__(self): Base1.__init__(self) Base2.__init__(self) def greeting(self): print("Hello from MultiDerived") d = MultiDerived() d.greeting() print(d.val1) print(d.val2)
多重继承可以极大地增加代码复杂度,因此应该在设计时仔细考虑是否需要使用多重继承。
四、super()函数
super()函数可以用来调用父类的方法。它有助于确保在多重继承时,所有父类的方法都被正确地调用。在下面的例子中,Parent类有一个greeting方法,而Child类从Parent类继承,同时它自己也定义了一个greeting方法。使用super()函数来调用Parent类的构造方法和greeting方法。
class Parent: def __init__(self): self.val = 100 def greeting(self): print("Hello from Parent") class Child(Parent): def __init__(self): super().__init__() self.val = 200 def greeting(self): super().greeting() print("Hello from Child") c = Child() c.greeting() print(c.val)
使用super()函数可以帮助我们在多重继承时正确地调用父类方法,并且让代码更加简洁易读。
五、方法解析顺序(MRO)
MRO(Method Resolution Order)用于解决多重继承时的方法调用问题。在Python中,MRO使用C3线性化算法来确定调用顺序。C3线性化算法基于DFS(Depth First Search)深度优先遍历,可以确保在有向无环图(DAG)中,继承关系为“单调扩展图”的所有类的正确方法解析顺序。下面的代码展示了如何使用__mro__属性来获得类的MRO。
class A: def do_something(self): print("Method defined in: A") class B(A): def do_something(self): print("Method defined in: B") super().do_something() class C(A): def do_something(self): print("Method defined in: C") super().do_something() class D(B, C): def do_something(self): print("Method defined in: D") super().do_something() d = D() d.do_something() print(D.__mro__)
以上代码中,D类继承自B和C类,并且在do_something()方法中使用super()函数调用了父类的方法。由于MRO的存在,super().do_something()会优先调用B类中的do_something()方法,然后调用A类中的do_something()方法,最终输出结果。