协议和扩展
使用protocol来声明一个协议。
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
类,枚举和结构体都可以使用协议。
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
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
试一试:
写一个枚举遵循上面的协议。
注意在simpleStructure的声明中关键字mutating的使用,它用来标记这个方法修改了这个结构体。而在simpleClass的声明中则不需要使用mutating,因为类中的方法总是可以被修改的。
使用extension来为已经存在的类型添加功能,就像新的方法和计算属性一样。你可以用extension为已经声明的类型添加协议,甚至是类库中自带的类型。
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42
}
}
7.simpleDescription
试一试:
为Double类型写一个扩展,为其添加一个(绝对值)absoluteValue的属性。
使用协议名就像使用其他类型名一样——例如,创建一个不同类型对象的集合,但是这些对象都遵循一个单一的协议。当值的类型是协议类型时,在协议定义以外的方法是不可用的。
let protocolValue: ExampleProtocol = a
protocolValue.simpleDescription
即使
protocolValue有一个运行时类型(
simpleClass),编译器同样会把它看作是
ExampleProtocol类型。也就是说,你不能访问除了遵循协议以外的类的方法和属性。