在 Python 中,继承使子类自动获得父类的属性和方法,并可在子类中追加字段或重写同名方法以改变行为。公共逻辑置于父类、差异置于子类,可减少重复代码。子类若定义自己的 __init__,须通过 super().__init__ 调用父类初始化,否则父类中设置的属性可能缺失。本节说明单继承、方法重写及多重继承的基本规则。

继承示例

在类名后的括号中列出父类,子类即挂到该继承链上。下例中 Dog 重写 speak,仍是 Animal 的实例,isinstance 为真:

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name} 发出声音")

class Dog(Animal):
    def speak(self):
        print(f"{self.name} 汪汪!")

d = Dog("旺财")
d.speak()
print(isinstance(d, Animal))

基本语法

语法为 class 子类(父类)。子类即使几乎为空,也可使用父类的方法及在父类 __init__ 中设置的属性:

Animal 父类 Dog 子类:重写 speak Cat 子类:直接继承
Dog、Cat 继承 Animal 后自动拥有父类的属性与方法(如 eat),子类可以重写方法改变行为。
class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name} 在吃东西")

class Cat(Animal):
    pass

c = Cat("咪咪")
c.eat()
print(c.name)

super() 调用父类

子类定义 __init__ 时,不会自动执行父类 __init__。需要父类初始化时,应使用 super().__init__(...),再设置子类特有字段:

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed

d = Dog("旺财", "金毛")
print(d.name, d.breed)

方法重写

子类定义与父类同名的方法即覆盖父类实现。对一组不同子类对象调用同一方法名,各自执行子类版本,这是多态的常见实现方式:

class Animal:
    def speak(self):
        print("...")

class Dog(Animal):
    def speak(self):
        print("汪汪!")

class Cat(Animal):
    def speak(self):
        print("喵喵!")

for a in [Dog(), Cat()]:
    a.speak()

多层继承

子类可再被继承,形成继承链。最底层实例可沿链调用祖先类的方法:

class A:
    def fa(self):
        print("A")

class B(A):
    def fb(self):
        print("B")

class C(B):
    def fc(self):
        print("C")

c = C()
c.fa()
c.fb()
c.fc()

多重继承

一个类可同时继承多个父类。同名方法冲突时由方法解析顺序(MRO)决定调用哪一个;括号中靠前的父类通常优先。能力组合复杂时宜谨慎使用:

class Swim:
    def swim(self):
        print("游泳")

class Run:
    def run(self):
        print("跑步")

class Duck(Swim, Run):
    pass

d = Duck()
d.swim()
d.run()

isinstance 与 issubclass

isinstance(对象, 类型) 判断对象是否为该类型或其子类的实例。issubclass(子, 父) 判断类之间是否存在继承关系:

print(isinstance(d, Duck))
print(isinstance(d, Swim))
print(issubclass(Duck, Run))
print(issubclass(Duck, int))

常见错误

  • 子类定义 __init__ 却未调用 super().__init__ 时,父类中应存在的属性可能未设置。
  • 继承层次过深会增加阅读成本,有时用组合(在对象中持有另一对象)更清晰。
  • 多重继承下同名方法依赖 MRO,结果可能与直觉不一致,宜保持父类职责单一。

本节说明了 Python 中继承的语法、super() 及方法重写。下一节介绍多态:鸭子类型与统一接口调用。