三、 函数、类与面向对象编程 (OOP)
- 标题:
- 函数参数与高阶函数
- 装饰器与闭包
- 面向对象三大特征
- 类、对象与魔术方法
- 异常处理
结论先行
面向对象三大特征层层递进:封装隐藏内部实现 → 继承复用并扩展已有能力 → 多态让不同对象对同一消息做出各自响应。封装是基础,继承是桥梁,多态是升华,三者共同支撑"高内聚、低耦合"的设计目标。🎯
1. 封装(Encapsulation)
核心:把数据和操作数据的方法绑定在一起,并对外隐藏内部实现细节。
Python 通过命名约定实现访问控制(注意是"约定"而非强制):
name:公开,外部可访问_name:受保护,提示"内部使用"(外部仍可访问)__name:私有,触发名称改写(_ClassName__name),增加访问难度
class BankAccount:
def __init__(self, balance):
self.__balance = balance # 私有属性
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self):
return self.__balance
🔒 意义:防止外部直接篡改内部状态,通过方法做校验,保证数据完整性。
2. 继承(Inheritance)
核心:子类获得父类的属性和方法,实现代码复用与扩展。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal): # 继承 Animal
def speak(self): # 重写父类方法
return f"{self.name}: 汪汪!"
关键点:
- Python 支持单继承和多继承,多继承通过 MRO(方法解析顺序,C3 线性化)决定查找顺序
super()调用父类方法,常用于__init__中初始化父类属性- 子类可重写(override)父类方法,也可扩展新增方法
🌱 意义:减少重复代码,建立"is-a"关系层次,支持渐进式扩展。
3. 多态(Polymorphism)
核心:不同类的对象对同一方法调用,表现出不同行为。Python 的多态基于鸭子类型(Duck Typing)——“看起来像鸭子,叫起来像鸭子,那就是鸭子”。
class Cat(Animal):
def speak(self):
return f"{self.name}: 喵喵!"
def make_sound(animal):
print(animal.speak()) # 不关心具体类型,只要有 speak 方法
make_sound(Dog("旺财")) # 旺财: 汪汪!
make_sound(Cat("咪咪")) # 咪咪: 喵喵!
🦆 Python 多态的特点:
- 不需要显式继承也能多态(鸭子类型),只要方法名一致即可
- 相比 Java/C++ 的接口/虚函数,Python 更灵活但缺少编译期类型约束
三者的联系
具体关系:
- 封装是地基:没有封装,数据和逻辑散落各处,继承无从谈起——继承的正是被封装好的属性和方法。
- 继承是纽带:它建立了类之间的层次关系,为多态提供了类型基础。子类继承父类的接口约定,才能被"统一调用"。
- 多态是成果:封装保证了接口稳定,继承让子类共享接口,多态则让"同一调用,各展所长"成为可能。
一句话串联:封装定义边界,继承传递能力,多态释放灵活——三者共同构成面向对象设计的"铁三角"。 🔺
预测结论先行
多态之后,面向对象思想会自然向抽象(接口/协议)→ 设计模式 → 组合优于继承 → 多范式融合演进,核心驱动力是从"单个类的灵活"走向"系统级的可扩展与可维护"。🚀
演进预测链
逐级说明
-
抽象(Abstraction) 🎯
多态的极致是"只认接口,不认实现"。Python 通过abc.ABC、typing.Protocol定义契约,让多态从隐式鸭子类型升级为显式接口约束。 -
设计模式 🧩
有了封装/继承/多态三件套,接下来就是用它们组合出可复用的设计经验——工厂、策略、观察者、装饰器等 23 种经典模式,本质都是对三大特征的工程化运用。 -
组合优于继承 ⚖️
继承链过深会导致强耦合和"脆弱基类问题"。下一步趋势是用组合 + 委托替代深层继承,这也是 Go 语言干脆取消继承的设计哲学。 -
多范式融合 🌐
纯 OOP 难以应对所有场景,现代 Python 已融合函数式(高阶函数、不可变数据)、装饰器/AOP(切面)、类型注解等,走向多范式协作的复杂系统设计。
一句话总结:三大特征解决了"单个类怎么设计",下一步解决的是"多个类怎么协作、整个系统怎么演进"。 🏗️