Python 九阳神功之贰:面向对象(下)

第 2 篇 · 功法:面向对象(下)· 继承衣钵,多态江湖

师门传承是为继承,一招百式是为多态。
下篇传授「继承」与「多态」的武林绝学,让你站在巨人的肩膀上,一招鲜吃遍天。

1. 继承

1.1 什么是继承

子类自动继承父类所有的属性和方法。

继承链示例
plain 复制代码
Animal(动物基类)
  ├── IsLandAnimal(陆地生物)
  │   └── CatAnimal(猫科动物)
  │       ├── Tiger(老虎)
  │       └── Cat(猫)
  ├── OceanAnimal(海洋生物)
  └── AirAnimal(空中生物)
python 复制代码
# 基类
class Animal:
    def __init__(self, name="基础动物类"):
        self.name = name

# 单继承
class IsLandAnimal(Animal):
    pass

# 多级继承
class CatAnimal(IsLandAnimal):
    pass

class Tiger(CatAnimal):
    pass

print(Tiger().name)   # 输出: 基础动物类

1.2 方法重写

子类定义和父类同名的方法,即覆盖父类方法。

python 复制代码
class Animal:
    def call(self):
        print("动物在叫")

class Cat(Animal):
    def call(self):          # 重写父类方法
        print("喵喵喵")

c = Cat()
c.call()   # 喵喵喵(优先找子类,找不到再找父类)

1.3 方法执行顺序

子类 → 父类 → 父类的父类 → ... → object → 报错

python 复制代码
class Cat(Animal):
    def call(self):
        print("喵喵喵")

c = Cat()
c.call()      # 子类有 → 执行子类
c.sleep()     # 子类没有 → 找父类
c.test()      # 父类也没有 → 找 object → 还没有 → 报错

1.4 子类调用父类方法(三种方式)

python 复制代码
class Car:
    def run(self):
        print("汽车在跑")

class HyBirdCar(Car):
    def run(self):
        # 方式1:super().方法名()
        super().run()

        # 方式2:super(当前类名, self).方法名()
        super(HyBirdCar, self).run()

        # 方式3:父类名.方法名(self)
        Car.run(self)

1.5 子类构造调用父类构造

python 复制代码
class Car:
    def __init__(self, car_name, car_color):
        self.car_name = car_name
        self.car_color = car_color

class HyBirdCar(Car):
    def __init__(self, car_name, car_color, car_type):
        # 公共属性走父类构造
        super().__init__(car_name, car_color)
        # 扩展属性自己写
        self.car_type = car_type

2. 多继承

2.1 基本语法

python 复制代码
class Child(Father, Monther):   # 多继承
    pass

2.2 方法冲突

如果多个父类有同名方法 ,按继承顺序(从左到右)优先调用第一个匹配的。

python 复制代码
class Father:
    def work(self):
        print("爸爸工作")

class Monther:
    def work(self):
        print("妈妈工作")

class Child(Father, Monther):
    def work(self):
        Monther.work(self)   # 可以指定调用哪个父类的方法

c = Child()
c.work()   # 如果子类没有 work,会调用 Father.work()

2.3 MRO(方法解析顺序)

使用 类名.__mro__类名.mro() 查看执行顺序。

python 复制代码
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass

print(D.__mro__)   # (<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)
print(D.mro())     # 同上

super() 严格遵循 MRO 顺序去查找方法。

3. 多态

3.1 什么是多态

同一个方法名,传入不同的对象,表现出不同的行为

3.2 多态的条件

  1. 有继承
  2. 有方法重写
  3. 父类引用指向子类对象

3.3 多态示例

python 复制代码
class PayBase:
    def pay(self):
        print("基础支付")

class WeChat(PayBase):
    def pay(self):
        print("微信支付")

class AliPay(PayBase):
    def pay(self):
        print("支付宝支付")

def pay_way(obj):
    if isinstance(obj, PayBase):   # 类型检查
        obj.pay()

pay_way(WeChat())   # 微信支付
pay_way(AliPay())   # 支付宝支付

4. 类属性、类方法、静态方法

4.1 类属性

类和所有实例共享 的属性,适合做统计汇总

python 复制代码
class Tool:
    tool_count = 0   # 类属性

    def __init__(self, tool_name):
        self.tool_name = tool_name
        Tool.tool_count += 1   # 每创建一个实例,计数+1

t1 = Tool("斧子")
t2 = Tool("锤子")
print(Tool.tool_count)   # 输出: 2(推荐用类名调用)
print(t1.tool_count)     # 输出: 2(实例也可以调用)
调用方式 说明
Tool.tool_count ✅ 推荐
t1.tool_count ⚠️ 可以,但不推荐(容易和实例属性混淆)

4.2 类方法

使用 @classmethod 装饰,第一个参数是 cls(类本身),可访问类属性。

python 复制代码
class Tool:
    tool_count = 0

    @classmethod
    def show_tool_count(cls):
        print(f"当前创建了 {cls.tool_count} 个工具")

Tool.show_tool_count()   # 调用类方法

4.3 静态方法

使用 @staticmethod 装饰,不需要 self 或 cls 参数,相当于普通函数,但属于类的命名空间。

python 复制代码
class Tool:
    @staticmethod
    def show_help_info():
        print("这是工具类的帮助信息")

Tool.show_help_info()   # 调用静态方法

5. 游戏小案例(综合实战)

需求:设计一个 Game 类

类型 名称 说明
类属性 top_score 记录历史总积分
实例属性 player_name 记录当前玩家姓名
静态方法 show_help() 显示游戏帮助信息
类方法 show_all_score() 显示历史总积分
实例方法 start_game() 开始当前玩家的游戏
python 复制代码
import random

class Game:
    top_score = 0   # 类属性

    def __init__(self, player_name):
        self.player_name = player_name

    @staticmethod
    def show_help():
        print("游戏帮助信息")

    @classmethod
    def show_all_score(cls):
        print(f"历史总积分:{cls.top_score}")

    def start_game(self):
        print(f"{self.player_name} 开始玩游戏")
        score = random.randint(100, 200)
        Game.top_score += score
        print(f"本轮得分:{score}")

g1 = Game("张三")
g1.start_game()
g2 = Game("李四")
g2.start_game()
Game.show_all_score()   # 累加了两轮得分

6. 快速记忆表(下篇)

概念 关键词 说明
继承 class 子类(父类) 复用父类属性和方法
重写 同名方法 覆盖父类方法
super() 调用父类方法 避免硬编码父类名
MRO __mro__ 方法解析顺序
多继承 class A(B, C) 继承多个父类
多态 同一个方法不同行为 继承 + 重写
类属性 类名.属性 所有实例共享
类方法 @classmethod 操作类属性
静态方法 @staticmethod 普通函数,归类管理
相关推荐
2601_965958462 小时前
口腔黏膜脱皮超2周未愈建议及时就医
人工智能·python
AI_小站2 小时前
刚面完百度的 Agent 开发岗,我才发现:世界就是个巨大的草台班子
java·开发语言·人工智能·spring·百度·langchain
微小冷3 小时前
在不同空间中展示数据(欧式、球面、庞加莱圆盘)
python·双曲空间·微分几何·geomstats·庞加莱圆盘·球面
felixking3 小时前
C++20 协程
开发语言·c++·协程
weixin_431600443 小时前
Agent Workflow 学习向:Code 节点,比模板更强的变量加工
后端·python·学习·ai·
讲温控就好了3 小时前
从医疗影像到能源存储——芯片冷却温控技术的跨行业赋能
人工智能·python·能源
DeepVisionary4 小时前
从 Qwen3.8-27B 把原生多模态、原生 FP8、桌面级 Agent 三件事一次集齐,看开源大模型的“工业化拐点“
python·自动化
Zane1994124 小时前
CAS 与原子类:Java 如何实现无锁编程
java·开发语言
固定资产管理系统软件5 小时前
商务局RFID固定资产管理系统的应用价值与落地要点解析
大数据·python