跳到主要内容

Swift中的协议

提示
  1. 协议的基本定义:在Swift中,协议定义了类或其他类型应实现的方法或属性蓝图,使用protocol关键字定义。
  2. 类遵守协议:类通过实现协议规定的方法或属性来遵守协议,如同提供了这些方法或属性的实际实现。
  3. 协议的扩展和继承:Swift允许协议继承其他协议,增加新的要求;同时可以通过扩展为协议提供默认实现。

在 Swift 中,协议定义了一系列可被类(或其他类型)采用的方法或属性的蓝图。

我们使用 protocol 关键字来定义协议。例如,

protocol Greet {

// 属性的蓝图
var name: String { get }

// 方法的蓝图
func message()
}

这里,

  • Greet - 协议的名称
  • name - 一个可获取的属性
  • message() - 方法定义,没有任何实现

注意

  • 协议只包含方法或属性的定义,而不是它们的实际实现。
  • 协议必须指定属性是可获取的还是可设置和可获取的。

使类遵守 Swift 协议

在 Swift 中,要使用协议,其他类必须遵守它。当我们使一个类遵守协议后,我们必须提供方法的实际实现。

以下是使类遵守协议的方法,

// 使类遵守 Greet 协议
class Employee: Greet {

// 实现属性
var name = "Perry"

// 实现方法
func message() {
print("早上好!")
}
}

这里,我们使 Employee 类遵守了 Greet 协议。因此,我们必须提供 name 属性和 message() 方法的实现。

示例 1:Swift 协议

protocol Greet {

// 属性的蓝图
var name: String { get }

// 方法的蓝图
func message()
}

// 使类遵守 Greet 协议
class Employee: Greet {

// 实现属性
var name = "Perry"

// 实现方法
func message() {
print("早上好", name)
}
}

var employee1 = Employee()
employee1.message()

输出

早上好 Perry

在上述示例中,我们创建了一个名为 Greet 的协议。协议包含了 name 属性和 message() 方法的蓝图。

这里,Employee 类遵守了 Greet 并提供了 namemessage() 的实际实现。

示例 2:用 Swift 协议计算面积

protocol Polygon {

func getArea(length: Int, breadth: Int)
}

// 使类遵守 Polygon 协议
class Rectangle: Polygon {

// 实现方法
func getArea(length: Int, breadth: Int) {
print("矩形的面积:", length * breadth)
}
}

// 创建一个对象
var r1 = Rectangle()

r1.getArea(length:5, breadth: 6)

输出

矩形的面积: 30

在上述示例中,我们创建了一个名为 Polygon 的协议。协议包含了带有两个参数 lengthbreadthgetArea() 方法的蓝图。 这里,Rectangle 类遵循了 Polygon 协议并提供了 getArea() 方法的实际实现。

func getArea(length: Int, breadth: Int) {
print("矩形的面积:", length * breadth)
}

遵循多个协议

在 Swift 中,一个类也可以遵循多个协议。例如,

protocol Sum {
...
}

protocol Multiplication {
...
}

class Calculate: Sum, Multiplication {
...
}

这里,名为 Calculate 的类遵循了 SumMultiplication 协议。

示例 3:遵循多个协议

// 创建 Sum 协议
protocol Sum {

func addition()
}

// 创建 Multiplication 协议
protocol Multiplication {

func product()
}

// 让类遵循两个协议
class Calculate: Sum, Multiplication {

var num1 = 0
var num2 = 0

func addition () {
let result1 = num1 + num2
print("和:", result1)
}

func product () {
let result2 = num1 * num2
print("积:", result2)
}

}

// 创建一个对象
var calc1 = Calculate()

// 为属性赋值
calc1.num1 = 5
calc1.num2 = 10

// 访问方法
calc1.addition()
calc1.product()

输出

: 15
: 50

在上述示例中,我们创建了两个协议:SumMultiplication。我们还创建了一个名为 Calculate 的类,遵循这两个协议。

我们在 SumMultiplication 协议中分别创建了名为 addition()product() 的方法的蓝图。

protocol Sum {

func addition()
}

protocol Multiplication {

func product()
}

由于 Calculate 遵循了 SumMultiplication,我们在类内部提供了 addition()product() 的实际实现。

最后,我们使用 calc1 类的对象访问了这些方法。

// 访问方法
calc1.addition()
calc1.product()

Swift 协议继承

类似于类,协议也可以继承其他协议。例如,

protocol Car {
...
}

protocol Brand: Car {
...
}

这里,Brand 协议继承了 Car 协议。现在,如果任何类实现了 Brand,它应该为 CarBrand 的所有属性提供实现。

示例 4:Swift 协议继承

protocol Car {
var colorOptions: Int { get }
}

// 继承 Car 协议
protocol Brand: Car {
var name: String { get }
}

class Mercedes: Brand {

// 必须实现两个协议的所有属性
var name: String = ""
var colorOptions: Int = 0
}

var car1 = Mercedes()
car1.name = "梅赛德斯 AMG"
car1.colorOptions = 4

print("名称:", car1.name)
print("颜色选项:", car1.colorOptions)

输出

名称: 梅赛德斯 AMG
颜色选项: 4

在上述示例中,Brand 协议继承了 Car 协议。

这里,Mercedes 类仅遵循 Brand。但由于 Brand 继承了 Car,我们需要实现 CarBrand 的所有属性。

注意:一个协议可以继承多个协议。例如,

protocol A {
...
}
protocol B {
...
}

protocol C: A, B {
...
}

协议扩展

在 Swift 中,我们可以使用 extension 关键字扩展协议。例如,

// 协议定义
protocol Brake {
func applyBrake()
}

// 定义遵循 Brake 的类
class Car: Brake {
var speed: Int = 0

func applyBrake() {
print("刹车已应用")
}
}

// 扩展协议
extension Brake {
func stop() {
print("引擎已停止")
}
}

let car1 = Car()
car1.speed = 61
print("速度:", car1.speed)

car1.applyBrake()

// 访问扩展的协议
car1.stop()

输出

速度: 61
刹车已应用
引擎已停止

在上述示例中,我们创建了名为 Brake 的协议,它定义了函数 applyBrake()

我们扩展了 Brake 协议并在其中定义了 stop() 函数。

// 扩展协议
extension Brake {
func stop() {
print("引擎已停止")
}
}

我们可以使用 car1 对象访问扩展的协议。

// 访问扩展的协议
car1.stop()