一、核心原则
只有在协议本体中声明的方法,conforming 类型才能重写 protocol extension 的默认实现。
- 协议声明 = “多态契约”
- extension 默认实现 = “默认行为”
- conforming 类型实现 = “覆盖(override)默认行为”
二、最小示例
// 1️⃣ 协议声明多态方法
protocol Greeter {
func greet() // ✅ 协议声明,多态点
}
// 2️⃣ 提供默认实现
extension Greeter {
func greet() {
print("Hello from default implementation")
}
}
// 3️⃣ 类型覆盖默认实现
struct Person: Greeter {
func greet() {
print("Hello from Person")
}
}
// 4️⃣ 调用
let g: Greeter = Person()
g.greet()
输出:
Hello from Person
✅ 默认实现被覆盖,保证了多态。
三、为什么这样可行
greet()在协议中声明 → 进入 witness table- extension 提供默认实现 → 如果类型没有提供自己的实现,就使用
- 类型提供实现 → 替换 witness table 中默认实现
- 通过协议类型调用 → 动态派发,最终调用 conforming 类型实现
四、工程级模板(可复用模式)
protocol Renderer {
func draw() // 多态点
}
extension Renderer {
func draw() { // 默认实现
print("default draw")
}
func render() { // 模板方法,可调用 draw()
prepare()
draw()
finish()
}
func prepare() {
print("prepare")
}
func finish() {
print("finish")
}
}
struct MetalRenderer: Renderer {
func draw() { // 覆盖默认实现
print("Metal draw")
}
}
let renderer: Renderer = MetalRenderer()
renderer.render()
// 输出:
// prepare
// Metal draw
// finish
特点:
draw()是多态点 → conforming 类型可覆盖render()是模板方法 → 静态派发,默认行为可复用- 组合 extension + 协议声明 = 既可复用,又可重写
五、设计口诀
协议声明 = 多态契约
协议扩展默认实现 = 工具或默认行为
conforming 类型实现 = 覆盖默认实现(动态派发)