协议 #
一、协议概述 #
协议定义了适合特定任务的属性、方法和下标的蓝图,可以被类、结构体和枚举采纳。
1.1 协议特点 #
- 定义接口规范
- 支持多协议采纳
- 支持协议继承
- 支持协议扩展
二、定义协议 #
2.1 基本语法 #
swift
protocol Drawable {
func draw()
var area: Double { get }
}
class Circle: Drawable {
var radius: Double
init(radius: Double) {
self.radius = radius
}
func draw() {
print("画圆")
}
var area: Double {
return Double.pi * radius * radius
}
}
2.2 属性要求 #
swift
protocol Named {
var name: String { get set }
var id: Int { get }
}
struct Person: Named {
var name: String
let id: Int
}
var person = Person(name: "张三", id: 1)
print(person.name)
2.3 方法要求 #
swift
protocol Greetable {
func greet(name: String) -> String
}
class Greeter: Greetable {
func greet(name: String) -> String {
return "Hello, \(name)!"
}
}
let greeter = Greeter()
print(greeter.greet(name: "Swift"))
2.4 可变方法要求 #
swift
protocol Toggleable {
mutating func toggle()
}
enum Switch: Toggleable {
case on, off
mutating func toggle() {
switch self {
case .on:
self = .off
case .off:
self = .on
}
}
}
var lightSwitch = Switch.off
lightSwitch.toggle()
print(lightSwitch)
三、协议扩展 #
3.1 默认实现 #
swift
protocol Greetable {
func greet() -> String
}
extension Greetable {
func greet() -> String {
return "Hello!"
}
}
struct Person: Greetable {
var name: String
}
let person = Person(name: "张三")
print(person.greet())
3.2 添加约束 #
swift
extension Collection where Element: Numeric {
func sum() -> Element {
return reduce(0, +)
}
}
let numbers = [1, 2, 3, 4, 5]
print(numbers.sum())
3.3 协议组合 #
swift
protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
func wishHappyBirthday(to celebrator: Named & Aged) {
print("生日快乐, \(celebrator.name), 你\(celebrator.age)岁了!")
}
struct Person: Named, Aged {
var name: String
var age: Int
}
let person = Person(name: "张三", age: 25)
wishHappyBirthday(to: person)
四、协议继承 #
4.1 基本继承 #
swift
protocol Animal {
var name: String { get }
func speak()
}
protocol Pet: Animal {
var owner: String { get }
}
class Dog: Pet {
var name: String
var owner: String
init(name: String, owner: String) {
self.name = name
self.owner = owner
}
func speak() {
print("汪汪")
}
}
4.2 类专用协议 #
swift
protocol ClassOnly: AnyObject {
func doSomething()
}
class MyClass: ClassOnly {
func doSomething() {
print("执行操作")
}
}
五、关联类型 #
5.1 基本用法 #
swift
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
var items: [Int] = []
var count: Int {
return items.count
}
mutating func append(_ item: Int) {
items.append(item)
}
subscript(i: Int) -> Int {
return items[i]
}
}
5.2 类型约束 #
swift
protocol Container {
associatedtype Item: Equatable
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}
六、协议作为类型 #
6.1 协议类型 #
swift
protocol Drawable {
func draw()
}
class Circle: Drawable {
func draw() { print("画圆") }
}
class Square: Drawable {
func draw() { print("画方") }
}
let shapes: [Drawable] = [Circle(), Square()]
shapes.forEach { $0.draw() }
6.2 委托模式 #
swift
protocol DownloadDelegate: AnyObject {
func downloadDidFinish(data: Data)
func downloadDidFail(error: Error)
}
class Downloader {
weak var delegate: DownloadDelegate?
func download(url: URL) {
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 1)
DispatchQueue.main.async {
self.delegate?.downloadDidFinish(data: Data())
}
}
}
}
class ViewController: DownloadDelegate {
func downloadDidFinish(data: Data) {
print("下载完成")
}
func downloadDidFail(error: Error) {
print("下载失败")
}
}
七、实际应用 #
7.1 网络请求协议 #
swift
protocol APIRequest {
associatedtype Response: Decodable
var path: String { get }
var method: String { get }
var parameters: [String: Any]? { get }
}
extension APIRequest {
var method: String { return "GET" }
var parameters: [String: Any]? { return nil }
}
struct UserRequest: APIRequest {
typealias Response = User
let path: String
init(userId: Int) {
self.path = "/users/\(userId)"
}
}
7.2 构建器协议 #
swift
protocol Builder {
associatedtype Product
func build() -> Product
}
class URLBuilder: Builder {
private var components = URLComponents()
func setScheme(_ scheme: String) -> URLBuilder {
components.scheme = scheme
return self
}
func setHost(_ host: String) -> URLBuilder {
components.host = host
return self
}
func setPath(_ path: String) -> URLBuilder {
components.path = path
return self
}
func build() -> URL? {
return components.url
}
}
let url = URLBuilder()
.setScheme("https")
.setHost("api.example.com")
.setPath("/users")
.build()
7.3 策略模式 #
swift
protocol SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T]
}
struct AscendingSort: SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T] {
return array.sorted()
}
}
struct DescendingSort: SortStrategy {
func sort<T: Comparable>(_ array: [T]) -> [T] {
return array.sorted(by: >)
}
}
class Sorter {
private var strategy: SortStrategy
init(strategy: SortStrategy) {
self.strategy = strategy
}
func sort<T: Comparable>(_ array: [T]) -> [T] {
return strategy.sort(array)
}
}
八、总结 #
本章学习了Swift协议:
- 协议定义:属性和方法要求
- 协议扩展:默认实现
- 协议继承:继承其他协议
- 关联类型:泛型协议
最佳实践:
- 面向协议编程
- 使用协议扩展提供默认实现
- 使用委托模式解耦
- 合理使用关联类型
下一章,我们将学习扩展!
最后更新:2026-03-26