Swift 协议

在本教程中,我们将通过实例学习 Swift 协议。

在 Swift 中,协议定义了方法或属性的蓝图,然后可以被类(或任何其他类型)采用。

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

  1. protocol Greet {
  2. // blueprint of a property
  3. var name: String { get }
  4. // blueprint of a method
  5. func message()
  6. }

这里,

  • Greet — 协议名称

  • name - 一个 gettable 属性

  • message() - 没有任何实现的方法定义

注意,协议只保存方法或属性定义,而不是它们的实际主体。协议必须指定属性是可读的或可读可写的。

使类符合 Swift 协议

在 Swift 中,要使用协议,其他类必须符合协议。在我们使类符合协议之后,我们必须提供该方法的实际实现。

下面是如何使类符合协议,

  1. // conform class to Greet protocol
  2. class Employee: Greet {
  3. // implementation of property
  4. var name = "Perry"
  5. // implementation of method
  6. func message() {
  7. print("Good Morning!")
  8. }
  9. }

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


实例 1:Swift 协议

  1. protocol Greet {
  2. // blueprint of property
  3. var name: String { get }
  4. // blueprint of a method
  5. func message()
  6. }
  7. // conform class to Greet protocol
  8. class Employee: Greet {
  9. // implementation of property
  10. var name = "Perry"
  11. // implementation of method
  12. func message() {
  13. print("Good Morning", name)
  14. }
  15. }
  16. var employee1 = Employee()
  17. employee1.message()

结果为:

  1. Good Morning Perry

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

这里,Employee 类符合 Greet,并提供 namemessage() 的实际实现。


实例 2:计算面积的 Swift 协议

  1. protocol Polygon {
  2. func getArea(length: Int, breadth: Int)
  3. }
  4. // conform the Polygon protocol
  5. class Rectangle: Polygon {
  6. // implementation of method
  7. func getArea(length: Int, breadth: Int) {
  8. print("Area of the rectangle:", length * breadth)
  9. }
  10. }
  11. // create an object
  12. var r1 = Rectangle()
  13. r1.getArea(length:5, breadth: 6)

结果为:

  1. Area of the rectangle: 30

在上面的例子中,我们创建了一个名为 Polygon 的协议。该协议包含带有两个参数的getArea() 方法的蓝图:length 长度和 breadth 宽度。

在这里,Rectangle 类符合 Polygon,并提供了 getArea() 方法的实际实现。

  1. func getArea(length: Int, breadth: Int) {
  2. print("Area of the rectangle:", length * breadth)
  3. }

符合多个协议

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

  1. protocol Sum {
  2. ...
  3. }
  4. protocol Multiplication {
  5. ...
  6. }
  7. class Calculate: Sum, Multiplication {
  8. ...
  9. }

这里,名为 Calculate 的类符合 SumMultiplication 协议。

实例 3:符合多个协议
  1. // create Sum protocol
  2. protocol Sum {
  3. func addition()
  4. }
  5. // create Multiplication protocol
  6. protocol Multiplication {
  7. func product()
  8. }
  9. // conform class to two protocols
  10. class Calculate: Sum, Multiplication {
  11. var num1 = 0
  12. var num2 = 0
  13. func addition () {
  14. let result1 = num1 + num2
  15. print("Sum:", result1)
  16. }
  17. func product () {
  18. let result2 = num1 * num2
  19. print("Product:", result2)
  20. }
  21. }
  22. // create an object
  23. var calc1 = Calculate()
  24. // assign values to properties
  25. calc1.num1 = 5
  26. calc1.num2 = 10
  27. // access methods
  28. calc1.addition()
  29. calc1.product()

结果如下:

  1. Sum: 15
  2. Product: 50

在上面的实例中,我们创建了两个协议:SumMultiplication。此外,我们还创建了一个名为 Calculate 的类,它符合这两个协议。

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

  1. protocol Sum {
  2. func addition()
  3. }
  4. protocol Multiplication {
  5. func product()
  6. }

由于 Calculate 符合 SumMultipalization,因此我们在类中提供了 addition()product() 的实际实现。

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

  1. // access methods
  2. calc1.addition()
  3. calc1.product()

Swift 协议继承

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

  1. protocol Car {
  2. ...
  3. }
  4. protocol Brand: Car {
  5. ...
  6. }

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

实例 4: Swift 协议继承
  1. protocol Car {
  2. var colorOptions: Int { get }
  3. }
  4. // inherit Car protocol
  5. protocol Brand: Car {
  6. var name: String { get }
  7. }
  8. class Mercedes: Brand {
  9. // must implement properties of both protocols
  10. var name: String = ""
  11. var colorOptions: Int = 0
  12. }
  13. var car1 = Mercedes()
  14. car1.name = "Mercedes AMG"
  15. car1.colorOptions = 4
  16. print("Name:", car1.name)
  17. print("Color Options:", car1.colorOptions)

结果如下:

  1. Name: Mercedes AMG
  2. Color Options: 4

在上面的实例中,Brand 协议继承了 Car 协议。

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

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

  1. protocol A {
  2. ...
  3. }
  4. protocol B {
  5. ...
  6. }
  7. protocol C: A, B {
  8. ...
  9. }

协议扩展

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

  1. // protocol definition
  2. protocol Brake {
  3. func applyBrake()
  4. }
  5. // define class that conforms Brake
  6. class Car: Brake {
  7. var speed: Int = 0
  8. func applyBrake() {
  9. print("Brake Applied")
  10. }
  11. }
  12. // extend protocol
  13. extension Brake {
  14. func stop() {
  15. print("Engine Stopped")
  16. }
  17. }
  18. let car1 = Car()
  19. car1.speed = 61
  20. print("Speed:", car1.speed)
  21. car1.applyBrake()
  22. // access extended protocol
  23. car1.stop()

结果如下:

  1. Speed: 61
  2. Brake Applied
  3. Engine Stopped

在上面的实例中,我们创建了定义函数 applyBrake() 的协议 Brake

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

  1. // extend protocol
  2. extension Brake {
  3. func stop() {
  4. print("Engine Stopped")
  5. }
  6. }

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

  1. // access extended protocol
  2. car1.stop()