Swift 开发教程系列 - 第12章:协议与协议扩展
协议(Protocol)是 Swift 的一种重要特性,它界说了实现特定功能的方法、属性或其他要求。通过协议,可以将行为界说从具体实现中分离,使代码更具可读性和扩展性。Swift 的协议支持协议扩展,这一特性答应我们为协议界说默认实现,使得协议不但仅是一个要求的集合,还可以具备部分功能。12.1 什么是协议
协议界说了一组用于实现特定功能的方法或属性。任何符合该协议的范例都必须实现这些方法和属性,确保符合协议的范例拥有相似的功能和行为。
协议示例
protocol Drivable {
var speed: Double { get set }
func drive()
}
class Car: Drivable {
var speed: Double = 0.0
func drive() {
print("Driving at \(speed) km/h")
}
}
let myCar = Car()
myCar.speed = 80.0
myCar.drive()// 输出:"Driving at 80.0 km/h"
在上例中,Drivable 协议要求任何符合该协议的范例都必须实现 speed 属性和 drive() 方法。Car 类遵照 Drivable 协议,并提供了具体的实现。
12.2 协议中的属性和方法
协议不但可以界说方法,还可以界说属性和下标(subscript)。协议中的属性可以是只读的,也可以是可读写的。
[*]只读属性:使用 { get } 声明只读属性,符合该协议的范例必须实现此属性。
[*]可读写属性:使用 { get set } 声明可读写属性,符合该协议的范例必须支持读取和写入。
示例代码
protocol Identifiable {
var id: String { get }
}
struct User: Identifiable {
var id: String
}
let user = User(id: "12345")
print("User ID: \(user.id)")// 输出:"User ID: 12345"
在上例中,Identifiable 协议界说了一个只读属性 id,符合协议的范例 User 实现了此属性。
12.3 协议的继续
Swift 的协议支持继续,可以从一个协议继续多个协议,并添加本身的要求。
示例代码
protocol Vehicle {
var maxSpeed: Double { get }
}
protocol Drivable: Vehicle {
func drive()
}
class Bicycle: Drivable {
var maxSpeed: Double = 25.0
func drive() {
print("Cycling at a safe speed.")
}
}
let bike = Bicycle()
bike.drive()// 输出:"Cycling at a safe speed."
在上例中,Drivable 协议继续自 Vehicle 协议,这意味着任何符合 Drivable 的范例必须同时满意 Vehicle 的要求。
12.4 协议组合
Swift 支持将多个协议组合在一起,界说一个新范例,该范例必须同时符合多个协议的要求。
示例代码
protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
struct Person: Named, Aged {
var name: String
var age: Int
}
func printInfo(of person: Named & Aged) {
print("\(person.name) is \(person.age) years old")
}
let alice = Person(name: "Alice", age: 30)
printInfo(of: alice)// 输出:"Alice is 30 years old"
在上例中,函数 printInfo 的参数范例 Named & Aged 表示参数必须同时符合 Named 和 Aged 协议。
12.5 协议扩展
协议扩展答应你为协议提供默认实现,使得符合该协议的范例可以直接使用这些实现,而无需自行实现。如许可以避免代码重复,并使协议的行为更为同等。
示例代码
protocol Greetable {
var name: String { get }
func greet()
}
extension Greetable {
func greet() {
print("Hello, \(name)!")
}
}
struct Friend: Greetable {
var name: String
}
let friend = Friend(name: "John")
friend.greet()// 输出:"Hello, John!"
在上例中,Greetable 协议的扩展提供了 greet() 方法的默认实现,因此符合协议的 Friend 结构体可以直接调用 greet() 方法,而无需本身实现。
12.6 协议的应用场景
[*]接口筹划:通过协议界说模块的公共接口,使代码更具模块化和可读性。
[*]依赖注入:使用协议替换具体范例,可以实现更灵活的依赖注入。
[*]委托模式:在委托模式中,协议用于界说委托对象的方法和属性,使不同范例的对象可以通过协议举行交互。
[*]范例约束:在泛型编程中,使用协议作为范例约束,确保泛型范例符合特定要求。
委托模式示例
protocol DataSource {
func fetchData() ->
}
class TableView {
var dataSource: DataSource?
func reloadData() {
if let data = dataSource?.fetchData() {
print("Data: \(data)")
}
}
}
class DataProvider: DataSource {
func fetchData() -> {
return ["Item 1", "Item 2", "Item 3"]
}
}
let tableView = TableView()
tableView.dataSource = DataProvider()
tableView.reloadData()// 输出:"Data: ["Item 1", "Item 2", "Item 3"]"
在上例中,DataSource 协议界说了 fetchData() 方法,使 TableView 类不需要知道具体的数据来源,而是通过协议获取数据。
12.7 协议的优点
[*]灵活性:协议可以资助实现松耦合的筹划,使代码更具模块化和灵活性。
[*]可扩展性:协议扩展使得协议不但是一个要求的集合,还可以包罗默认实现,方便扩展协议的功能。
[*]代码复用:通过协议和协议扩展,可以避免重复代码,提高代码的复用性。
[*]范例安全:Swift 的范例查抄确保协议实现的安全性,避免了运行时错误。
通过本章的学习,你将会发现协议在 Swift 开发中饰演着至关重要的角色,使代码更加灵活、可扩展,而且容易维护。下一章将探讨 Swift 的错误处理机制(Error Handling),资助你编写更加健壮和稳定的代码。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]