协议可以要求遵循协议的类型实现某些指定的实例方法或类方法。这些方法作为协议的一部分,像普通方法一样放在协议的定义中,但是不需要大括号和方法体。可以在协议中定义具有可变参数的方法,和普通方法的定义方式相同。但是,不支持为协议中的方法提供默认参数。
正如属性要求中所述,在协议中定义类方法的时候,总是使用 static
关键字作为前缀。即使在类实现时,类方法要求使用 class
或 static
作为关键字前缀,前面的规则仍然适用:
protocol SomeProtocol {
static func someTypeMethod()
}
下面的例子定义了一个只含有一个实例方法的协议:
protocol RandomNumberGenerator {
func random() -> Double
}
RandomNumberGenerator
协议要求遵循协议的类型必须拥有一个名为 random
, 返回值类型为 Double
的实例方法。尽管这里并未指明,但是我们假设返回值是从 0.0
到(但不包括)1.0
。
RandomNumberGenerator
协议并不关心每一个随机数是怎样生成的,它只要求必须提供一个随机数生成器。
如下所示,下边是一个遵循并符合 RandomNumberGenerator
协议的类。该类实现了一个叫做 线性同余生成器(linear congruential generator) 的伪随机数算法。
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
}
}
let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())")
// 打印 “Here's a random number: 0.37464991998171”
print("And another one: \(generator.random())")
// 打印 “And another one: 0.729023776863283”