-
協(xié)議:
規(guī)定了用來實現(xiàn)某一特定任務(wù)或者功能的方法、屬性小槐,以及其他需要的東西.
- #####寫法:
使用protocol
關(guān)鍵字表明這是一個協(xié)議,在要遵守協(xié)議的類名后使用":協(xié)議名"來遵循協(xié)議,擁有父類的類型,父類放在最前面,用,
隔開
protocol SomeProtocol { //協(xié)議定義 } class SomeClass { //類定義 } class SomeSubClass:SomeClass,SomeProtocol { //類定義 }
- 遵循了一個協(xié)議,就需要實現(xiàn)協(xié)議中的屬性,方法,構(gòu)造器
- ######協(xié)議屬性:
Swift協(xié)議內(nèi),屬性不確定是存儲屬性還是計算屬性,只提供名稱和類型,具體實現(xiàn)由其遵循的類來定義.同時,必須標(biāo)明它是可讀寫,還是只讀,通過{set get}
標(biāo)明可讀寫,通過{get}
表示只讀,同理,使用static
,class
表明屬性為類屬性
```
protocol SomeProtocol {
var anotherName:String{get}
static func getStr(a:String) ->String
}
class Person: SomeProtocol {
var anotherName: String {
return "name"
}
static var name :String {
return "name"
}
}
Person.name
var some = Person()
some.anotherName
```
- ######協(xié)議方法:
Swift協(xié)議內(nèi),不寫方法的具體實現(xiàn),只定義方法名稱,方法參數(shù)類型,返回類型,具體實現(xiàn)由其遵循的類來定義.同理,使用static
,class
表明方法為類方法
protocol SomeProtocol { func getName()->String static func getStr(a:String) ->String } class Person: SomeProtocol { func getName() -> String { return "name" } static func getStr(a: String) -> String { return a+"!" } } Person.getStr(a: "aaa") var person = Person() person.getName()
- ######協(xié)議構(gòu)造器:
Swift協(xié)議內(nèi),不寫構(gòu)造器的具體實現(xiàn),只提供構(gòu)造器參數(shù),具體實現(xiàn)由其遵循的類來定義.
實現(xiàn)協(xié)議構(gòu)造器時,需要使用required
關(guān)鍵字來修飾,同時,添加了required
關(guān)鍵字,就表示了該類的子類也擁有該構(gòu)造器.
如果一個類的協(xié)議構(gòu)造器跟父類的構(gòu)造器相同,則必須同時加上required
以及override
關(guān)鍵字
protocol SomeProtocol { init(name:String) } class Person { var name:String init(name: String) { self.name = name } } class AnotherPerson:Person,SomeProtocol { required override init(name: String) { super.init(name: name) } } var person = AnotherPerson(name: "Allen") person.name
- ######協(xié)議作為類型
Swift中,協(xié)議可以作為參數(shù),返回值,也可以作為屬性類型,也可以作為Collection
類型的元素類型
protocol SomeProtocol { init(name:String) } class Person { var name:String var someClass:SomeProtocol init(name: String,someClass:SomeProtocol) { self.name = name self.someClass = someClass } func getSomeClass()->(SomeProtocol) { return self.someClass } } class AnotherPerson:SomeProtocol{ required init(name: String) { print(name) } } var person = Person(name: "name", someClass: AnotherPerson(name: "protocol")) var someClass = person.getSomeClass() var array = [someClass]
- #####代理:
代理模式,一個類,委托某部分功能由代理實現(xiàn).可以用來響應(yīng)特定的動作蛙紫,或者接收外部數(shù)據(jù)源提供的數(shù)據(jù)拍屑,而無需關(guān)心外部數(shù)據(jù)源的類型。
protocol SomeProtocol { func negative() func zero() func positive() } class Person { var someClass:SomeProtocol? func judgeInt(numbers:[Int]) { for number in numbers { switch number { case 0: someClass?.zero() case let number where number < 0: someClass?.negative() default: someClass?.positive() } } } } class AnotherPerson:SomeProtocol{ func negative() { print("-") } func zero() { print("0") } func positive() { print("+") } } var person = Person() person.judgeInt(numbers: [-1,0,11]) person.someClass = AnotherPerson() person.judgeInt(numbers: [-1,0,11,22,11])
- ######通過擴展使類滿足協(xié)議
protocol SomeProtocol { subscript(index:Int)->Int { get } } extension Int:SomeProtocol { subscript(time:Int)->Int { return self*time } } 3[3]
- ######協(xié)議可以被另一個協(xié)議繼承,這時遵循改子類協(xié)議的對象,必須同時實現(xiàn)子協(xié)議與父協(xié)議的方法
protocol SomeProtocol { subscript(index:Int)->Int { get } } protocol SubProtocol:SomeProtocol { subscript(index:String)->String { get } } extension Int:SubProtocol { internal subscript(index: String) -> String { return index + String(self) } subscript(time:Int)->Int { return self*time } } 3[3] 3["3"]
- ######類專屬協(xié)議:
Swift中,可以通過在協(xié)議后添加:class
來表明這個協(xié)議只能被類類型遵從,如果該協(xié)議有繼承的父協(xié)議,使用,
隔開,寫在class后
protocol SomeProtocol { } protocol SubProtocol:class,SomeProtocol { } extension Int:SubProtocol { }
- ######合并協(xié)議:
在某些特定環(huán)境中,例如方法參數(shù)類型,我們有時候需要把多個協(xié)議要求合成,這是如果使用","號會報錯,同時,如果使用(,)
會將其變?yōu)樵M,Swift中提供了&
符號來合并協(xié)議.合并協(xié)議并不會生成新的協(xié)議,它只作用在某個特定的區(qū)域內(nèi)
protocol SomeProtocol:class { } protocol AnotherProtocol:class { } func composition(class:SomeProtocol&AnotherProtocol){ }
- #####檢查是否符合協(xié)議,使用"is","as?","as!"來判斷,
- ######is:
用來檢查實例是否符合某個協(xié)議坑傅,若符合則返回 true僵驰,否則返回 false。
- ######as?:
返回一個可選值唁毒,當(dāng)實例符合某個協(xié)議時蒜茴,返回類型為協(xié)議類型的可選值,否則返回 nil浆西。
- ######as!:
將實例強制向下轉(zhuǎn)換到某個協(xié)議類型粉私,如果強轉(zhuǎn)失敗,會引發(fā)運行時錯誤
protocol SomeProtocol { } extension Int:SomeProtocol { } var array:[Any] = ["str",1] for item in array { if let object = item as? SomeProtocol { print("\(object)符合協(xié)議") }else { print("\(item)不符合協(xié)議") } }
- #####可選協(xié)議要求:
上面介紹的,不管是在協(xié)議中定義屬性,方法,構(gòu)造器,都是方法必須實現(xiàn)的.Swift中,我們可以定義協(xié)議中的某個要求為可選要求.在協(xié)議中使用optional
作為前綴來定義可選要求.可選要求只能被Objective-C類或者@Objc的類遵循,所以必須在協(xié)議和要求前寫上@objc
@objc protocol Name { @objc optional func printName() func printAnotherName() } //報錯,因為String不是objc類型 //extension String:Name { // //} extension NSString:Name { func printAnotherName() { print("name") } }
- #####擴展協(xié)議:
協(xié)議可以通過擴展來為遵循協(xié)議的類型提供屬性室谚、方法以及下標(biāo)的實現(xiàn).實現(xiàn)后,每個遵循協(xié)議的類不需要再定義擴展中實現(xiàn)的某個要求
protocol Name { func printAnotherName() } extension Name { func printAnotherName() { print("name") } } class SomeClass:Name { } SomeClass().printAnotherName()