Python多继承案例
基本语法
class Father:
def __init__(self, name):
self.name = name
print(f"Father __init__: {self.name}")
def skill(self):
return "会修车"
def hobby(self):
return "喜欢钓鱼"
class Mother:
def __init__(self, name):
self.name = name
print(f"Mother __init__: {self.name}")
def skill(self):
return "会做饭"
def hobby(self):
return "喜欢种花"
# 多继承:同时继承Father和Mother
class Child(Father, Mother):
def __init__(self, name, age):
# 注意:多继承时只调用第一个父类的__init__
super().__init__(name)
self.age = age
print(f"Child __init__: {self.name}, {self.age}")
def show_all_skills(self):
# 演示方法解析顺序(MRO)
print(f"技能:{self.skill()}") # 调用Father的skill
print(f"爱好:{self.hobby()}") # 调用Father的hobby
# 使用示例
child = Child("小明", 10)
child.show_all_skills()
print(f"Child的MRO顺序:{Child.__mro__}")
MRO(方法解析顺序)示例
class A:
def method(self):
return "A"
class B(A):
def method(self):
return "B"
class C(A):
def method(self):
return "C"
class D(B, C):
def method(self):
return "D"
# 查看MRO
print(D.__mro__)
# 输出:(<class '__main__.D'>, <class '__main__.B'>,
# <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
d = D()
print(d.method()) # 输出:D
钻石继承(菱形继承)问题
class Animal:
def __init__(self, name):
print("Animal __init__")
self.name = name
class Mammal(Animal):
def __init__(self, name, has_fur=True):
print("Mammal __init__")
super().__init__(name)
self.has_fur = has_fur
class Bird(Animal):
def __init__(self, name, can_fly=True):
print("Bird __init__")
super().__init__(name)
self.can_fly = can_fly
class Bat(Mammal, Bird): # 会飞的哺乳动物
def __init__(self, name):
print("Bat __init__")
super().__init__(name)
# 测试钻石继承
bat = Bat("蝙蝠")
print(f"名字:{bat.name}")
print(f"有毛皮:{bat.has_fur}")
print(f"会飞:{bat.can_fly}")
print(f"Bat的MRO:{Bat.__mro__}")
使用super()正确处理多继承
class Base1:
def __init__(self):
print("Base1 __init__")
super().__init__()
class Base2:
def __init__(self):
print("Base2 __init__")
super().__init__()
class MultiChild(Base1, Base2):
def __init__(self):
print("MultiChild __init__")
super().__init__()
# 测试super()链式调用
mc = MultiChild()
print(f"MRO: {MultiChild.__mro__}")
实际应用示例:混合类
class LogMixin:
"""日志功能混合类"""
def log(self, message):
print(f"[{self.__class__.__name__}] {message}")
class TimeMixin:
"""时间处理混合类"""
def get_timestamp(self):
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
class User(LogMixin, TimeMixin):
"""用户类继承多个功能混合类"""
def __init__(self, name):
self.name = name
def save(self):
self.log(f"保存用户:{self.name}")
print(f"时间戳:{self.get_timestamp()}")
# 使用示例
user = User("张三")
user.save()
方法重写与super()调用
class FileHandler:
def open_file(self, filename):
print(f"FileHandler: 打开文件 {filename}")
def close_file(self):
print("FileHandler: 关闭文件")
class EncryptedFileHandler(FileHandler):
def open_file(self, filename):
print("EncryptedFileHandler: 解密")
super().open_file(filename) # 调用父类方法
def close_file(self):
super().close_file() # 调用父类方法
print("EncryptedFileHandler: 加密")
class CompressedFileHandler(FileHandler):
def open_file(self, filename):
print("CompressedFileHandler: 解压")
super().open_file(filename)
def close_file(self):
super().close_file()
print("CompressedFileHandler: 压缩")
# 多重继承组合
class SuperFileHandler(EncryptedFileHandler, CompressedFileHandler):
def open_file(self, filename):
print("SuperFileHandler: 开始处理")
super().open_file(filename)
def close_file(self):
super().close_file()
print("SuperFileHandler: 处理完成")
# 测试
handler = SuperFileHandler()
handler.open_file("test.txt")
print("---")
handler.close_file()
- MRO(方法解析顺序):Python使用C3线性化算法,通过
ClassName.__mro__查看
- super()的正确使用:在多继承中使用
super()可以正确调用下一个类的方法
- init方法:多继承时,
super().__init__()会按照MRO顺序调用父类初始化方法
- 混合类(Mixin):通常用于添加特定功能,类名通常以Mixin结尾
- 钻石继承:Python通过MRO机制解决了钻石继承的问题
最佳实践
- 尽量使用
super()而不是直接调用父类名
- 混合类不应该有
__init__方法,或者其__init__应该接受*args, **kwargs
- 使用
__mro__检查方法解析顺序,避免意外
- 多继承会增加复杂度,谨慎使用
