使用protocol
來聲明一個協議。javascript
protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() }
類、枚舉和結構體均可以實現協議。java
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
練習: 寫一個實現這個協議的枚舉。nginx
注意聲明SimpleStructure
時候mutating
關鍵字用來標記一個會修改結構體的方法。SimpleClass
的聲明不須要標記任何方法,由於類中的方法一般能夠修改類屬性(類的性質)。swift
使用extension
來爲現有的類型添加功能,好比新的方法和計算屬性。你能夠使用擴展在別處修改定義,甚至是從外部庫或者框架引入的一個類型,使得這個類型遵循某個協議。框架
extension Int: ExampleProtocol { var simpleDescription: String { return "The number \(self)" } mutating func adjust() { self += 42 } } print(7.simpleDescription)
練習: 給
Double
類型寫一個擴展,添加absoluteValue
功能。spa
你能夠像使用其餘命名類型同樣使用協議名——例如,建立一個有不一樣類型可是都實現一個協議的對象集合。當你處理類型是協議的值時,協議外定義的方法不可用。code
let protocolValue: ExampleProtocol = a print(protocolValue.simpleDescription) // print(protocolValue.anotherProperty) // Uncomment to see the error
即便protocolValue
變量運行時的類型是simpleClass
,編譯器會把它的類型當作ExampleProtocol
。這表示你不能調用類在它實現的協議以外實現的方法或者屬性。對象