我们什么时候应该使用协议继承?——Swift 协议继承的应用与思

在 Swift 中,协议(Protocol)是一种强大的抽象工具,它让我们可以只关注「行为」而不是具体「实现」。协议不仅可以定义方法和属性要求,还可以继承其他协议,从而在代码中实现更清晰的分层设计。

但很多同学常常会问:什么时候应该使用协议继承?

今天,我们就一起来聊聊协议继承的应用场景、最佳实践,以及在实际项目中应该如何优雅使用。


💡 什么是协议继承?

协议继承其实非常简单:一个协议可以继承一个或多个其他协议,除了继承它们的要求之外,还可以添加自己的新要求。

swift 复制代码
protocol Vehicle {
    func start()
}

protocol ElectricVehicle: Vehicle {
    func charge()
}

上面,ElectricVehicle 继承了 Vehicle 协议,这意味着任何遵循 ElectricVehicle 的类型,必须同时实现 start()charge()


🟢 协议继承的应用场景

✅ 1. 按功能分解,组合更小的协议

当你的协议太大时,直接把所有要求都堆在一个协议里会非常笨重、难以维护。这时候可以将功能拆解成小协议,然后再通过继承组合成一个大协议。

swift 复制代码
protocol Drivable {
    func drive()
}

protocol Flyable {
    func fly()
}

protocol AmphibiousVehicle: Drivable, Flyable {}

这样,AmphibiousVehicle 就是「既能开也能飞」的交通工具,实现者必须同时满足两个功能。


✅ 2. 为不同层次的抽象设计协议

有时我们需要定义一些「更抽象」的行为,后面再细化。例如:

swift 复制代码
protocol Shape {
    func area() -> Double
}

protocol ColoredShape: Shape {
    var color: String { get set }
}
  • Shape 定义了基本形状的行为(计算面积)。
  • ColoredShape 继承 Shape 并增加颜色属性。

当我们需要「只关心形状」时,只使用 Shape;需要「带颜色的形状」时,使用 ColoredShape,这种分层设计思路更加清晰、灵活。


✅ 3. 给默认实现做准备

如果你有多个协议需要提供相似的默认实现,使用协议继承可以帮助你只写一次。

swift 复制代码
protocol Printable {
    func printInfo()
}

extension Printable {
    func printInfo() {
        print("This is a printable object.")
    }
}

protocol DetailedPrintable: Printable {
    func detailedDescription() -> String
}

extension DetailedPrintable {
    func printInfo() {
        print(detailedDescription())
    }
}

这样,DetailedPrintable 可以重写 printInfo(),但仍然保留 Printable 的默认实现。


⚡️ 使用协议继承的好处

可组合 :小协议组合大协议,灵活扩展。

更好的抽象层次 :让设计更符合「接口分离原则」。

减少耦合:调用方只依赖需要的协议,避免过度依赖具体实现。


❗️ 使用协议继承要注意什么?

  • ❌ 不要为了「好看」而滥用继承,把很多无关行为硬塞进一个协议里。
  • ✅ 遵循「单一职责原则」,一个协议最好只关心一件事,后续可以通过继承组合。
  • ✅ 谨慎考虑是否需要在协议中定义默认实现,如果太多默认实现,可能隐藏了实现者必须注意的逻辑。

🟢 总结

什么时候应该使用协议继承?

当你需要:

  • 分层抽象
  • 组合小协议
  • 为可选功能提供可重用的默认实现

这时候协议继承就是一个非常优雅、灵活的解决方案。

相关推荐
bug攻城狮20 小时前
Spring Boot Banner
java·spring boot·后端
whysqwhw20 小时前
Hippy 跨平台框架扩展原生自定义组件的完整实现方案对比
前端
MadPrinter20 小时前
SpringBoot学习日记 Day11:博客系统核心功能深度开发
java·spring boot·后端·学习·spring·mybatis
dasseinzumtode20 小时前
nestJS 使用ExcelJS 实现数据的excel导出功能
前端·后端·node.js
子兮曰20 小时前
🔥C盘告急!WSL磁盘暴增?三招秒清20GB+空间
前端·windows·docker
淦出一番成就20 小时前
Java反序列化接收多种格式日期-JsonDeserialize
java·后端
Jinuss21 小时前
Vue3源码reactivity响应式篇之EffectScope
前端·vue3
Java中文社群21 小时前
Hutool被卖半年多了,现状是逆袭还是沉寂?
java·后端
stoneship21 小时前
网页截图API-Npm工具包分享
前端
Jedi Hongbin21 小时前
Three.js shader内置矩阵注入
前端·javascript·three.js