一、核心区别一句话
| 特性 | 面向对象设计 (OOP) | 面向协议设计 (POP) |
|---|---|---|
| 核心思想 | 继承 hierarchies → 类型之间的 is-a 关系 | 行为契约(protocol) → 类型之间的 can-do 关系 |
| 复用方式 | 继承 + 方法重写 | 默认实现(extension) + 泛型组合 |
| 多态实现 | vtable / 动态派发 | witness table / 泛型 +协议约束 |
| 耦合度 | 类型紧密耦合,子类依赖父类实现 | 类型解耦,依赖协议契约而非具体实现 |
| 扩展性 | 继承层次固定 → 不易扩展 | 类型可以自由 conform 多个协议 → 易扩展 |
| 值类型支持 | 不原生 | POP 支持 struct / enum + 泛型 |
| 性能 | 动态派发可能开销大 | 泛型 + 静态派发可零开销抽象 |
总结:OOP 重“类型”,POP 重“能力 / 行为”。
二、直观对比例子
1️⃣ OOP 继承场景
class Animal {
func makeSound() {
print("Some sound")
}
}
class Dog: Animal {
override func makeSound() {
print("Woof!")
}
}
let a: Animal = Dog()
a.makeSound() // 输出: Woof!
特点:
- 通过继承实现多态
- 子类 tightly coupled → 依赖父类
- 类型与行为绑定,值类型支持差
2️⃣ POP 协议场景
protocol SoundMaker {
func makeSound()
}
extension SoundMaker {
func makeSound() {
print("Some sound") // 默认实现
}
}
struct Dog: SoundMaker {
func makeSound() {
print("Woof!")
}
}
let d: SoundMaker = Dog()
d.makeSound() // 输出: Woof!
特点:
- 类型无需继承 → 只 conform 协议
- 解耦,支持 struct / enum
- 可自由组合多协议 → 易扩展
- 默认实现提供复用,类型可覆盖
3️⃣ POP 的核心优势
- 解耦:依赖协议而不是具体类
- 组合能力:struct/enum + 多协议 → 代替深继承树
- 灵活扩展:不破坏已有代码即可添加新能力
- 零开销抽象:泛型 + 静态派发在性能关键路径比 OOP 快
三、工程级对比(何时用哪种)
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 共享行为 + 复杂继承 | OOP | class 多态天然 |
| 模块边界解耦 | POP | protocol 可替换实现、便于单元测试 |
| 值类型 / 高性能路径 | POP | 泛型 + struct 静态派发零成本 |
| 插件系统 / 可扩展能力 | POP | 多协议组合可随时增加能力 |
| UIKit / AppKit 组件 | OOP | class 系统 API 依赖继承和引用语义 |
四、关键对比口诀
OOP 重类型层次,POP 重行为契约;
OOP 用继承复用,POP 用协议组合;
OOP 动态派发,POP 泛型静态派发零开销。