協定文法
protocol TestProtocol{
//協定的定義部分
}
遵循協定:
struct TestStruct : TestProtocol{
//結構體定義部分
}
enum TestEnum : TestProtocol{
//枚舉定義部分
}
class TestClass : TestProtocol{
//類定義部分
}
注:繼承父類的類在遵循協定時,應該将繼承放在協定之前。
例子:
class ChildClass : SuperClass , TestProtocol ,OtherProtocol{
//類定義部分
}
隻能被類遵循的協定:
協定可指定隻能由類遵循,當結構體或者枚舉去遵循這個協定的時候:編譯報錯:Non-class type "xxx" cannot conform to class protocol 'xxx'類協定例子:
protocol ClassProtocol : class{
//協定文法
}
協定屬性:
協定不指定屬性是存儲型屬性還是計算型屬性,它隻指定屬性的名稱,類型和屬性是可讀還是可讀可寫(如果屬性是可讀可寫的,那麼該屬性不能是常量屬性或值)。
protocol TestProtocol{
var name : String {get set}
var age : Int{get}
static var testStatic : String{get set} :
}
遵循協定的簡單結構體例子:
struct TestStruct : TestProtocol{
var name : String //存儲型屬性,協定隻規定了必須要有一個可讀可寫的name屬性,并沒有要求計算型屬性還是存儲型屬性。
var age : Int{
get{
return 12 //舉例傳回值
}
}
static var testStatic : String = "Swift"
}
注:協定屬性指定為可讀,遵循的協定可以是可讀的或者可讀可寫的。協定屬性指定為可讀可寫,遵循的協定隻能是可讀可寫的。定義協定的時候隻能用var來定義,協定不能像類和結構體一樣用來初始化
注:可讀可寫性的了解:
var testStruct : TestStruct = TestStruct()testStruct.name = "EnumJun" //可讀可寫,編譯正常teststruct.age = 25//可讀可寫,編譯正常var testProtocol : TestProtocol = TesteStruct()testProtocol.name = "EnumJun //可讀可寫,編譯正常testProtocol.age = 25.//隻讀,編譯報錯:Cannot assign to property:'age' is a get-only property
協定方法:
協定可以指定遵循執行個體方法或者類方法。在協定的定義中,不需要大括号和方法體。可以在協定中定義具有可變參數的方法,不支援協定中的方法的參數提供預設值。
protocol FuncProtocol{
static func methodTest() //類型方法
func change() -> Double //帶傳回值無參的執行個體方法
func test(name:String, age:Int) //無傳回值的執行個體方法
}
遵循協定的Class例子:
class FuncClass : FuncProtocol{
static func methodTest(){
//類方法實作
}
func change() ->Double{
//執行個體方法内部實作
return 0.0
}
func test(name:String = "EmuJun",age:Int) {
//執行個體方法内部實作,參數提供預設值
}
}
mutating 方法要求:
首先介紹mutating關鍵字:
在結構體和枚舉中,将mutating關鍵字作為方法的字首,寫在func關鍵字之前,表示可以在該方法中修改它所屬的執行個體以及執行個體的任意屬性的值。如果沒有這個關鍵字,編譯報錯。協定可以由類,結構體,枚舉遵循,是以涉及到mutating關鍵字的使用。協定中定義執行個體方法:
如果需要在方法内部修改任意屬性的值,定義協定時需要在方法前加mutating關鍵字,使得結構體和枚舉能夠遵循此協定并滿足方法要求。例子:
protocol MutatingProtocol{
mutating func toggle()
}
枚舉遵循例子:
enum SwitchEnum : MutatingProtocol{
case Off , Onmutating func toggle()[
switch self{
case Off:
self = On //直接在func中修改屬性報錯,加入mutating 關鍵字可修改屬性。
case On:
self = Off
}
}
}
結構體遵循例子:
struct MutatingStruct : MutatingProtocol{
var name : Stringvar age : Intmutating func toggle(){
self.name = "EmuJun" //直接在func中修改屬性報錯。加上mutating關鍵字可修改屬性。self.age = 25
}}
類遵循例子:
class MutatingClass : MutatingProtocol{
var name : String
var age : Int
func toggle(){
self.name = "EmuJun". //類中不需要加入mutating關鍵字。
self.age = 25
}
}