用protocol 去声明协议。
protocol ExampleProtocol {
var simpleDescription: String { get }//表明属性只读
mutating func adjust()//表明这个方法可以修改属性
}
一般情况下,值类型的实例方法不能修改它的属性。mutating(变异)加在方法前,表示该方法可以修改属性的值,还可以给它隐含的self属性赋值一个全新的实例,这个新实例在方法结束后会替换原来的实例。
类,枚举,和结构体都可以继承协议。
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {//类方法前不需要加mutating,因为类是引用类型
simpleDescription += "Now 100% adjusted."
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += "(adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
使用extension给已有的类型增加新的东西,比如一个新方法和计算属性。你可以用extension给别的地方声明的类型或者甚至给你引进来的库或框架的一个类型修改定义,使得这个类型遵循某个协议。
extension Int : ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
print(7.simpleDescription)
你可以使用协议的名称像其他命名类型一样-比如,创建一个有不同类型都遵循一个协议的对象的集合。当你使用一个是协议类型的常量或变量时,定义在协议之外的方法不能调用。
let protocolValue: ExampleProtocol = a // a 是上面的SimpleClass()
print(protocolValue.simpleDescription)
print(protocolValue. anotherProperty) // 会报错
尽管protocolValue是一个ExampleProtocol的动态类型,但是编译器视它为ExampleProtocol类型。意味着除了遵循协议内的内容不能访问类的方法和属性。