引入
想像一下这个场景:
你正在开发一个游戏,需要创建各种角色 - 战士、法师、射手。你发现这些角色都有共同的特点:生命值、攻击力、移动方法…难道要每个类都重复写一遍吗?🤔
重复的代码让人头疼:
class Warrior:
def __init__(self, name, hp, attack):
self.name = name
self.hp = hp
self.attack = attack
def move(self):
print(f"{self.name} 正在移动")
def attack_enemy(self):
print(f"{self.name} 发动攻击,造成{self.attack}点伤害")
class Mage:
def __init__(self, name, hp, attack, mp):
self.name = name
self.hp = hp
self.attack = attack
self.mp = mp
def move(self):
print(f"{self.name} 正在移动")
def attack_enemy(self):
print(f"{self.name} 发动攻击,造成{self.attack}点伤害")
发现什么问题了吗?
重复!重复!还是重复!这不科学!难道程序员的时间不值钱吗?😫
别急,继承来拯救你!
class Character:
def __init__(self, name, hp, attack):
self.name = name
self.hp = hp
self.attack = attack
def move(self):
print(f"{self.name} 正在移动")
def attack_enemy(self):
print(f"{self.name} 发动攻击,造成{self.attack}点伤害")
class Warrior(Character):
pass
class Mage(Character):
def __init__(self, name, hp, attack, mp):
super().__init__(name, hp, attack)
self.mp = mp
代码瞬间清爽了!这就是继承的魔力!
1. 继承的概念
在现实生活中,孩子会继承父母的特征。在编程世界里,类也可以"继承"另一个类的属性和方法!
继承允许我们定义一个类,它从另一个类(父类)继承所有的方法和属性。子类可以添加自己的新方法、属性,或者重写父类的方法。
简单来说:
- 父类(基类):提供基础功能的类
- 子类(派生类):继承父类,并可以扩展或修改功能
打个比方:
# 父类就像是一个"汽车模板"
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
def drive(self):
print("汽车正在行驶")
def honk(self):
print("滴滴!")
# 子类就像是具体的"车型"
class ElectricCar(Car): # 电动车继承汽车的所有特性
def charge(self): # 并且还有自己特有的功能
print("正在充电...")
2. 继承的基本语法
在Python中,继承的语法很简单,只需要在定义类时在类名后的括号中指定父类:
class 子类名(父类名):
# 子类的定义
如果子类需要重写父类的构造方法,通常使用super()函数来调用父类的构造方法:
class Parent:
def __init__(self):
print("父类初始化")
class Child(Parent):
def __init__(self):
super().__init__() # 这行相当于 Parent.__init__(self)
print("子类初始化")
如果子类没有定义自己的构造方法,它会自动继承父类的构造方法。
3. 基本继承
让我们通过一个具体的例子来理解基本继承:
# 父类
# 父类 - 动物
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(f"{self.name} 正在吃东西")
def sleep(self):
print(f"{self.name} 正在睡觉")
def make_sound(self):
print("动物发出声音")
# 子类 - 狗继承自动物
class Dog(Animal): # 关键语法:类名(父类名)
# 注意:我们没有写__init__,直接使用父类的!
def make_sound(self): # 重写父类方法
print("汪汪汪!")
def fetch(self): # 子类特有的方法
print(f"{self.name} 正在接飞盘")
# 子类 - 猫也继承自动物
class Cat(Animal):
def make_sound(self):
print("喵喵喵!")
def climb_tree(self):
print(f"{self.name} 正在爬树")
class Bird(Animal): # 不重写make_sound
pass
my_dog = Dog("旺财", 3)
my_dog.eat() # 继承自父类
my_dog.make_sound() # 使用重写后的方法
my_dog.fetch() # 子类特有的方法
bird = Bird("小鸟", 1)
bird.make_sound() # 输出:"动物发出声音"(使用父类实现)
print(f"我的狗叫{my_dog.name},今年{my_dog.age}岁") # 继承的属性
4. 多层继承
现实世界中的继承往往不止一层:
# 爷爷辈
class Vehicle: # 交通工具
def __init__(self, speed, capacity):
self.speed = speed
self.capacity = capacity
def start(self):
print("交通工具启动")
# 爸爸辈
class Car(Vehicle): # 汽车继承交通工具
def __init__(self, speed, capacity, brand):
super().__init__(speed, capacity)
self.brand = brand
def drive(self):
print(f"{self.brand}汽车正在行驶")
# 儿子辈
class SportsCar(Car): # 跑车继承汽车
def __init__(self, speed, capacity, brand, turbo):
super().__init__(speed, capacity, brand)
self.turbo = turbo
def race_mode(self):
print("切换到赛道模式!")
self.speed += 50
# 来创建一辆超级跑车!
my_car = SportsCar(200, 2, "法拉利", True)
my_car.start() # 爷爷的方法
my_car.drive() # 爸爸的方法
my_car.race_mode() # 自己的方法
print(f"当前速度:{my_car.speed}") # 爷爷的属性
super() 是什么魔法?它为什么能调用父类的方法?
其实super() 就像是说:“爸爸,这个事情你来处理一下!”
5.多重继承
Python的独门绝技:一个类可以有多个爸爸!
# 第一个爸爸 - 会飞的
class Flyable:
def fly(self):
print("我在天空自由飞翔!")
def take_off(self):
print("准备起飞...")
# 第二个爸爸 - 会游泳的
class Swimmable:
def swim(self):
print("我在水中畅游!")
def dive(self):
print("潜入水中...")
# 第三个爸爸 - 会跑的
class Runnable:
def run(self):
print("我在陆地上奔跑!")
def jump(self):
print("跳跃!")
# 超级生物 - 继承所有能力!
class SuperCreature(Flyable, Swimmable, Runnable):
def __init__(self, name):
self.name = name
def show_off(self):
print(f"{self.name}开始展示绝技:")
self.take_off()
self.fly()
self.dive()
self.swim()
self.jump()
self.run()
# 创建超级生物
super_man = SuperCreature("超级小强")
super_man.show_off()
⚠️ 警告:多重继承虽好,但要小心!
钻石继承问题:
class A:
def method(self):
print("A的方法")
class B(A):
def method(self):
print("B的方法")
super().method()
class C(A):
def method(self):
print("C的方法")
super().method()
class D(B, C):
def method(self):
print("D的方法")
super().method()
d = D()
d.method() # 猜猜会输出什么?
6.方法解析顺序
当使用多重继承时,如果多个父类有同名的方法,Python需要确定调用哪个父类的方法。
这个确定过程遵循方法解析顺序(Method Resolution Order,MRO)。
class A:
def test(self):
print("A")
class B(A):
def test(self):
print("B")
super().test()
class C(A):
def test(self):
print("C")
super().test()
class D(B, C):
def test(self):
print("D")
super().test()
# 查看MRO顺序
print(D.__mro__)
# 输出:D -> B -> C -> A -> object
d = D()
d.test()
# 输出:D B C A
Python使用C3算法计算MRO,保证:
- 子类在父类之前
- 多个父类保持声明顺序
- 每个类只出现一次
实际应用技巧:
# 当你不确定继承关系时,随时查看MRO
class ComplexClass(A, B, C):
pass
print(ComplexClass.__mro__)
# 或者
print(ComplexClass.mro())
也可以:
class PracticalExample:
@classmethod
def check_inheritance(cls):
"""检查类的继承关系"""
print(f"父类: {cls.__bases__}")
print(f"MRO: {cls.mro()}")
在实际开发中,如果遇到复杂的多重继承关系,建议:
- 尽量减少多重继承的使用
- 使用组合替代继承
- 明确查看和理解MRO顺序
总结
继承让我们:
✅ 避免重复代码 - DRY原则(Don’t Repeat Yourself)
✅ 提高代码复用性 - 一次编写,多处使用
✅ 建立清晰的层次关系 - 像现实世界一样组织代码
✅ 便于维护和扩展 - 修改父类,所有子类受益
记住继承的三要素:
继承 - 获得父类的所有能力
重写 - 修改不适合的方法
扩展 - 添加新的功能
1236






