在 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__ 中设置的属性:
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() 及方法重写。下一节介绍多态:鸭子类型与统一接口调用。