一,协议
协议听起来挺高大上,其实就对应着 c++ 里面的基类
协议提供了一系列的方法和属性,但是并不实现它,只是对其名称等进行一个规范,其他类/结构体/枚举 都可以继承协议,并实现其中的功能,称之为遵循者
protocol SomeProtocol {
// 协议内容
}
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 类的内容
}
一个类可以继承多个协议,也可以同时继承父类和协议
1,协议的属性
protocol SomeProtocol {
var musBeSettable : Int { get set }
var doesNotNeedToBeSettable: Int { get } //可读,未规定是否可写
}
前面说到,协议是不实现具体功能的,但是可以标明属性的读写属性,如果只有get,说明是可读属性,但是并不代表只读,如果其他类实现了写的功能,那也不会报错
遵循者中,可以对协议中的属性进行扩展,但是必须完整地实现协议中所有属性方法,不能少,否则会报错
2,协议的方法
协议方法支持变长参数(variadic parameter),不支持默认参数(default parameter)。
文档中有这么一句话:前置class关键字表示协议中的成员为类成员;当协议用于被枚举或结构体遵循时,则使用static关键字。
不过经我测试,似乎swift2中已经不支持协议的类成员了,一律都得用static。
当然,如果什么都不加也行,只是标明是个方法
protocol SomeProtocol {
static func someTypeMethod()
}
protocol RandomNumberGenerator {
func random() -> Double
}
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) % m)
return lastRandom / m
}
}
let generator = LinearCongruentialGenerator()
println("Here's a random number: \(generator.random())")
// 输出 : "Here's a random number: 0.37464991998171"
println("And another one: \(generator.random())")
// 输出 : "And another one: 0.729023776863283"
3,突变方法
协议是可能被结构体和枚举 遵循的,但是在结构体/枚举 中,方法是不能改变属性的
如果协议中的方法可能在未来需要改变其他属性,就需要加上mutating
当然,类在遵循协议的时候,不需要加mutating,因为类本来就可以改
protocol Togglable {
mutating func toggle()
}
enum OnOffSwitch: Togglable {
case Off, On
mutating func toggle() {
switch self {
case Off:
self = On
case On:
self = Off
}
}
}
var lightSwitch = OnOffSwitch.Off
lightSwitch.toggle()
//lightSwitch 现在的值为 .On
4,协议类型
虽然协议不实现任何功能,但是协议同样可以当作一个类型来使用,如果一个变量的类型为一个协议,那么它可以被赋值为任何遵循它的类型
class Dice {
let sides: Int
let generator: RandomNumberGenerator
init(sides: Int, generator: RandomNumberGenerator) {
self.sides = sides
self.generator = generator
}
func roll() -> Int {
return Int(generator.random() * Double(sides)) +1
}
}
如上,generator由于为RandomNumberGenerator的协议类型。所以它能够被赋值为任意遵循该协议的类型
也就是说,我们在这个类里只是给了一个接口,具体怎么样去实现这个功能,需要调用这个接口的开发者去完成。
这个功能是不是就像是c++11的函数指针
5,委托/代理模式
委托这是在类java语言中非常常用的特性