22:swift-协议
正文
/* 22:协议 1: 协议为方法、属性、以及其他特定的任务需求或功能定义蓝图。 协议可被类、结构体、或枚举类型采纳以提供所需功能的具体实现。 满足了协议中需求的任意类型都叫做遵循了该协议。 */ import UIKit /* 2:定义属性 2.1: 属性要求定义为变量属性,在名称前面使用 var 关键字。 2.2: 协议同时要求一个属性必须明确是 可读的 或 可读的和可写的。 2.3: 在协议中定义类型属性时在前面添加 static 关键字。 */ protocol SomeProtocol { var mustBeSettable: Int { get set } var doesNotNeedToBeSettable: Int { get } // 类型属性 static var someTypeProperty: Int { get set } } /* 3: 方法要求 协议可以要求采纳的类型实现指定的实例方法和类方法。 这些方法作为协议定义的一部分,书写方式与正常实例和类方法的方式完全相同,但是不需要大括号和方法的主体。 */ protocol RandomNumberGenerator { func random() -> Double } /* 4:异变方法要求 结构体和枚举 mutating 有时一个方法需要改变(或异变)其所属的实例。 例如值类型的实例方法(即结构体或枚举), 在方法的 func 关键字之前使用 mutating 关键字,来表示在该方法可以改变其所属的实例,以及该实例的所有属性。 */ protocol Togglable { mutating func toggle() } /* 5: 初始化器要求 协议可以要求遵循协议的类型实现指定的初始化器。和一般的初始化器一样,只用将初始化器写在协议的定义当中,只是不用写大括号也就是初始化器的实体: 你可以通过实现指定初始化器或便捷初始化器来使遵循该协议的类满足协议的初始化器要求。 在这两种情况下,你都必须使用 required 关键字修饰初始化器的实现: 由于 final 的类不会有子类,如果协议初始化器实现的类使用了 final 标记, 你就不需要使用 required 来修饰了。因为这样的类不能被继承子类。 */ protocol InitProtocol { init(someParameter: Int) } /* 6:使用扩展声明采纳协议 */ class Protocol22VC: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .white self.title = "22:协议" // 协议, let generator = LinearCongruentialGenerator() print("Here's a random number: \(generator.random())") // Prints "Here's a random number: 0.37464991998171" print("And another one: \(generator.random())") // Prints "And another one: 0.729023776863283" // 异变方法 var lightSwitch = OnOffSwitch.off lightSwitch.toggle() print("结构体异变方法协议:\(lightSwitch)") // 初始化协议 let classA = ClassA(someParameter: 1) } } class LinearCongruentialGenerator: RandomNumberGenerator { var lastRandom = 42.0 let m = 139968.0 let a = 3877.0 let c = 29573.0 func random() -> Double { lastRandom = ((lastRandom * a + c).truncatingRemainder(dividingBy:m)) return lastRandom / m } } // 开关结构体 enum OnOffSwitch: Togglable { case off, on mutating func toggle() { switch self { case .off: self = .on case .on: self = .off } } } class ClassA: InitProtocol { // 你可以通过实现指定初始化器或便捷初始化器来使遵循该协议的类满足协议的初始化器要求。在这两种情况下,你都必须使用 required 关键字修饰初始化器的实现: required init(someParameter: Int) { print("初始化协议:\(someParameter)") } }