Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain

第2章:Swift 协议的基础

2.4 协议的继承与组合

协议的继承与组合是 Swift 中增强协议功能和灵活性的重要机制。通过继承,协议可以复用和扩展其他协议的要求;通过组合,类型可以同时遵循多个协议,构建复杂的接口。这种设计不仅体现了协议化编程(POP)的模块化思想,还为开发者提供了强大的抽象工具。本节将详细探讨协议继承与组合的语法、使用场景和实际应用,帮助读者理解如何利用它们构建更丰富的代码结构。

协议继承

协议继承允许一个协议继承另一个或多个协议,从而包含其所有要求。继承使用与类继承类似的语法,在协议名称后使用冒号(:)列出父协议。例如:

protocol Named {
    var name: String { get }
}

protocol Describable: Named {
    var description: String { get }
}

在这个例子中,Describable 继承了 Named,因此它包含了 name 和 description 两个属性要求。遵循 Describable 的类型必须实现这两个属性:

struct Item: Describable {
    var name: String
    var description: String
}

let item = Item(name: "Book", description: "A programming book")
print(item.name)        // 输出: Book
print(item.description) // 输出: A programming book
多重继承

与类只能单继承不同,协议支持多重继承。例如:

protocol Identifiable {
    var id: String { get }
}

protocol Trackable: Named, Identifiable {
    func track()
}

Trackable 继承了 Named 和 Identifiable,因此包含 name、id 和 track() 三个要求。遵循者需要实现所有这些要求:

struct Package: Trackable {
    var name: String
    var id: String
    
    func track() {
        print("Tracking \(name) with ID: \(id)")
    }
}

let package = Package(name: "Parcel", id: "12345")
package.track() // 输出: Tracking Parcel with ID: 12345

协议的多重继承避免了类继承中的“菱形问题”,因为协议只定义要求,不涉及实现。

协议组合

协议组合允许类型或函数参数同时遵循多个协议,使用 & 符号连接多个协议名称。组合不涉及协议之间的继承关系,而是直接要求某个类型满足多个独立协议的要求。例如:

protocol Movable {
    func move()
}

protocol Resettable {
    func reset()
}

struct Machine: Movable & Resettable {
    func move() {
        print("Machine is moving")
    }
    
    func reset() {
        print("Machine reset")
    }
}

let machine = Machine()
machine.move()  // 输出: Machine is moving
machine.reset() // 输出: Machine reset
在函数参数中的应用

协议组合特别适用于函数参数或泛型约束,指定参数必须满足多个协议。例如:

func operate(on object: Movable & Resettable) {
    object.move()
    object.reset()
}

operate(on: machine)
// 输出:
// Machine is moving
// Machine reset

这种方式比定义一个继承多个协议的新协议更灵活,因为它不需要预先创建协议类型。

继承与组合的对比

特性协议继承协议组合
定义位置在协议定义时指定在使用时(类型或参数)指定
关系父子关系,扩展要求平行关系,临时组合
复用性创建可重用的新协议一次性组合,灵活应用
适用场景定义层次化的协议体系临时需要多种行为的场景
  • 继承适合构建系统的协议体系,例如 Swift 标准库中的 Sequence 和 Collection。
  • 组合适合动态组合行为,例如函数参数或临时类型要求。

实际应用示例

假设我们要设计一个表示“可报告状态的设备”的系统,可以结合继承和组合:

protocol StatusReportable {
    var status: String { get }
}

protocol Controllable {
    func start()
    func stop()
}

protocol Device: StatusReportable {
    var name: String { get }
}

struct SmartFan: Device, Controllable {
    var name: String
    var status: String
    
    func start() {
        print("\(name) started")
    }
    
    func stop() {
        print("\(name) stopped")
    }
}

func manage(device: Device & Controllable) {
    print("Status: \(device.status)")
    device.start()
    device.stop()
}

let fan = SmartFan(name: "Fan", status: "Idle")
manage(device: fan)
// 输出:
// Status: Idle
// Fan started
// Fan stopped
  • Device 继承了 StatusReportable,定义了设备的基本要求。
  • SmartFan 通过继承 Device 和组合 Controllable,实现了完整的设备功能。
  • manage 函数使用协议组合,确保参数同时具备 Device 和 Controllable 的行为。

注意事项

  1. 要求一致性:继承或组合的协议要求不能冲突,例如两个协议不能定义同名但签名不同的方法。
  2. 实现负担:多重继承或组合可能增加遵循者的实现工作量,需权衡设计复杂度。
  3. 类型安全:Swift 的类型系统会确保遵循者满足所有要求,编译器会在不匹配时报错。

小结

协议的继承与组合是 Swift 中扩展协议能力的重要工具。继承通过定义层次化的协议关系实现复用,组合则通过灵活拼接多个协议满足临时需求。两者结合使用,可以构建既模块化又适应性强的代码结构。下一节将探讨协议在不同类型(结构体、类和枚举)中的实现,进一步展示其广泛适用性。


Last Updated:: 3/9/25, 2:18 PM