一、引言
協議約定了一些屬性與方法,其作用類似Java中的抽象類,Swift中類型通過遵守協議來實現一些約定的屬性和方法。Swift中的協議使用protocol關鍵字來聲明。Swift中的協議還有一個十分有意思的特性,協議可以通過擴展來實現一些方法和附加功能。
二、在協議中定義屬性和方法
協議中定義的屬性只約定名稱和類型,在具體類型的實現中,其可以是存儲屬性也可以是計算屬性,協議中還需要指定屬性是可讀的還是可讀可寫的。示例代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
protocol MyPortocol { //定義實例屬性 //可讀的 var name:String{get} //可讀可寫的 var age:Int{set get} //可讀的 var nameAndAge:String{get} static var className:String{get} } class MyClass: MyPortocol { var name: String var age: Int var nameAndAge: String{ get{ return "\(name)"+"\(age)" } } static var className: String{ get{ return "MyClass" } } init(){ name = "HS" age = 24 } } |
有一點需要注意,協議中的可讀并不是只讀,協議中的屬性約定成可讀可寫,則在實現時,這個屬性必須是可讀可寫的,但是如果協議中約定成可讀的,則此屬性可以是只讀的也可以是可讀可寫的,看具體的實現。
協議中約定的方法可以是實例方法也可以是類型方法,示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
protocol MyPortocol { func logName() static func logClassName() } class MyClass: MyPortocol { var name: String var age: Int init(){ name = "HS" age = 24 } func logName() { print(name) } static func logClassName() { print(className) } } |
同樣,協議中也可以對構造方法進行定義約定。
三、協議的特點
協議中雖然沒有任何屬性和方法的實現,但是其仍然可以當做類型來使用,在函數參數、返回值中應用廣泛,示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
protocol MyPortocol { //定義實例屬性 var name:String{get} var age:Int{set get} var nameAndAge:String{get} static var className:String{get} func logName() static func logClassName() } //將協議類型作為參數 func test(param:MyPortocol) { param.logName() } |
協議作為類型這種用法另一個應用點是在集合類型中,協議可以作為所有遵守此協議的集合類型。
協議可以像其他類型一樣進行繼承,子協議將自動擁有父協議約定的屬性和方法。協議也可以通過class關鍵字來定義只有類可以進行遵守,示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
protocol MyPortocol { //定義實例屬性 var name:String{get} var age:Int{set get} var nameAndAge:String{get} static var className:String{get} func logName() static func logClassName() } //只有類可以繼承此協議 protocol MySubPortocol:class,MyPortocol { } |
協議既然可以像其他類型一樣進行使用,當然它也可以使用is,as?,as!進行檢查和轉換,關于is,as的更多用法可以查看Swift關于類型轉換的內容。
協議也可定義其中的屬性或方法為可選的,即遵守此協議的類可以實現也可以不實現可選的屬性和方法,然而,聲明為可選的需要此協議為@objc類型的,示例如下:
1
2
3
4
5
6
7
8
9
10
|
@objc protocol MyPortocol { //定義實例屬性 var name:String{get} var age:Int{set get} var nameAndAge:String{get} static var className:String{get} func logName() //可選實現 optional static func logClassName() } |
Swift中的協議還有一個十分重要的特性,其可以通過擴展來進行屬性、方法以及下標的實現。這對于一些通用類的方法十分方便,這相當于所有繼承此協議的類都默認實現了這樣的方法,示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
protocol MyPortocol { //定義實例屬性 var name:String{get} var age:Int{set get} var nameAndAge:String{get} static var className:String{get} func logName() static func logClassName() } extension MyPortocol{ var name:String{ return "HS" } } |