一、概覽
Swift協(xié)議.png
二泊业、協(xié)議的定義和遵守
/* Swift協(xié)議
1.可以定義方法、屬性啊易、下標(biāo)吁伺,屬性只能是var類型且不能寫初始值,表明讀寫性即可(包括類型屬性)
2.協(xié)議中定義的內(nèi)容默認(rèn)都是必須實(shí)現(xiàn)的
3.協(xié)議可以extension, 在擴(kuò)展中提供方法、屬性租谈、下標(biāo)的默認(rèn)實(shí)現(xiàn)后篮奄,
這些方法、屬性、下標(biāo)就變成可選實(shí)現(xiàn)的了;
4.協(xié)議中mutating修飾方法窟却,如果是值類型遵守協(xié)議時(shí)昼丑,
方法中修改了自身內(nèi)存要加mutating,不修改時(shí)可以不加mutating
5.聲明的初始化器夸赫,類中必須以required實(shí)現(xiàn)或者是final的類菩帝;
枚舉和結(jié)構(gòu)體中也必須實(shí)現(xiàn)但不用加required(枚舉實(shí)現(xiàn)初始化器可以給self賦值一個(gè))
*/
protocol ZLRunable {
// 1.協(xié)議中定義屬性,只能是var茬腿,寫法是后面表明讀寫即可
// a.在實(shí)現(xiàn)協(xié)議中對(duì)應(yīng)變量時(shí)呼奢,讀寫權(quán)限不小于協(xié)議中即可,并且可以是存儲(chǔ)屬性也可以是計(jì)算屬性
var speed: Int { set get }
// b.在實(shí)現(xiàn)協(xié)議中只讀的屬性時(shí)滓彰,如果是用存儲(chǔ)屬性實(shí)現(xiàn)控妻,可以是let州袒,也可以是var
var startTime: Int { get }
// 2.對(duì)于類型屬性揭绑,在協(xié)議中定義也是表明讀寫權(quán)限,實(shí)現(xiàn)時(shí)不小于協(xié)議中權(quán)限
// 如果是類中實(shí)現(xiàn)類型屬性郎哭,并且是用類型計(jì)算屬性實(shí)現(xiàn)他匪,可以用static和class修飾
static var name: String { get }
// 3.定義方法和類型方法不需要寫實(shí)現(xiàn)
func run()
// 4.如果是在類中實(shí)現(xiàn)類型方法,可以將static改為class修飾
static func bark()
// 5.下標(biāo)夸研、類型下標(biāo)方法跟屬性是類似的
/* static */subscript(minute: Int) -> Int { set get }
// 6.mutating方法用于表示如果是值類型遵守協(xié)議邦蜜,表明可能會(huì)涉及到修改自身變量值
// a.類中實(shí)現(xiàn)不需要加mutating,值類型中實(shí)現(xiàn)時(shí)如果方法不涉及修改自身變量也可以不加mutating
// b.協(xié)議中如果不寫mutating亥至,值類型遵守協(xié)議時(shí)悼沈,方法寫了mutating,那么構(gòu)成重載姐扮,還是要實(shí)現(xiàn)沒(méi)有mutating的方法
mutating func mutateFunc()
// 7.協(xié)議中聲明的初始化方法絮供,協(xié)議擴(kuò)展中不能自定義實(shí)現(xiàn)
// 類中必須以required實(shí)現(xiàn)或者是final的類;值類型中也必須實(shí)現(xiàn)但不用加required;
// 枚舉實(shí)現(xiàn)初始化器可以給self賦值一個(gè)
init(with no: Int, age: Int)
}
/* Swift協(xié)議擴(kuò)展
1.提供方法的默認(rèn)實(shí)現(xiàn)茶敏,這個(gè)方法就變成可選實(shí)現(xiàn)
2.提供屬性的默認(rèn)實(shí)現(xiàn)時(shí)壤靶,只能實(shí)現(xiàn)為計(jì)算屬性,
且如果默認(rèn)實(shí)現(xiàn)的屬性的讀寫權(quán)限小于協(xié)議中聲明惊搏,則還是必須實(shí)現(xiàn)的屬性
3.協(xié)議擴(kuò)展中可以新加方法和類型方法贮乳,外部不能直接通過(guò)協(xié)議調(diào)用,需要通過(guò)遵守協(xié)議的類型調(diào)用恬惯,
且如果遵守協(xié)議后重寫了方法向拆,則調(diào)用重寫的,沒(méi)有重寫則調(diào)用協(xié)議中的(重寫不需要加override)
4.協(xié)議擴(kuò)展中方法酪耳、屬性浓恳、下標(biāo)都是要自己實(shí)現(xiàn)的,不能僅僅是聲明
5.協(xié)議擴(kuò)展中不能寫初始化方法的實(shí)現(xiàn)
*/
extension ZLRunable {
// 1.提供方法的默認(rèn)實(shí)現(xiàn),這個(gè)方法就變成可選實(shí)現(xiàn)
func run() {
print("run---")
}
// 2.默認(rèn)實(shí)現(xiàn)屬性時(shí)奖蔓,如果讀寫權(quán)限小于協(xié)議中規(guī)定赞草,那么屬性還是必須實(shí)現(xiàn)的
// 如果有set、get時(shí)吆鹤,這個(gè)屬性就是可選實(shí)現(xiàn)的
var speed: Int {
set {}// 沒(méi)有這個(gè)set厨疙,這個(gè)屬性還是必須實(shí)現(xiàn)的
get { 1 }
}
// 3.實(shí)現(xiàn)下標(biāo)后,下標(biāo)變成可選實(shí)現(xiàn)
subscript(minute: Int) -> Int {
set {}
get { 1 }
}
// 4.新加的方法:外部通過(guò)遵守協(xié)議類型的實(shí)例調(diào)用疑务,如果有自己的實(shí)現(xiàn)沾凄,則調(diào)用自己的
public func extensionFunc1() {
print("ZLRunable.extension.extensionFunc1--")
}
// 5.新加的類型方法:外部通過(guò)遵守協(xié)議類型調(diào)用,如果有自己的實(shí)現(xiàn)知允,則調(diào)用自己的
public static func extensionFunc2() {
print("ZLRunable.extension.extensionFunc2--")
}
}
二撒蟀、協(xié)議的繼承和限定類遵守
/* Swift協(xié)議繼承
0.只能繼承類和協(xié)議,并且最多能繼承一個(gè)類温鸽,協(xié)議不限數(shù)量
1.協(xié)議中會(huì)擁有繼承的所有協(xié)議的接口保屯。
2.需要限定只能由類來(lái)遵守,可以繼承AnyObject涤垫,AnyObject從這里看來(lái)是一個(gè)協(xié)議
3.可以繼承一個(gè)類姑尺,這樣的話,只能是這個(gè)類的子類遵守,并且協(xié)議不再需要遵守AnyObject
5.如果不遵守AnyObject蝠猬,代表(枚舉切蟋、結(jié)構(gòu)體)值類型也可以遵守這個(gè)協(xié)議
*/
protocol ZLJumpable: ZLRabbit,/* AnyObject,*/ ZLRunable, CustomStringConvertible {
// ZLRabbit是個(gè)類,所以再遵守AnyObject是冗余的
}
三榆芦、方法參數(shù)要求多個(gè)協(xié)議
/// 例子:參數(shù)屬于某個(gè)類型柄粹,且需要遵守多個(gè)協(xié)議,使用&連接
func testProtocol(abc: UIView & CaseIterable & RawRepresentable) {
// do some thing
}
四匆绣、OC協(xié)議兼容
OC中協(xié)議都繼承NSObject協(xié)議驻右,并且只能是類遵守。
對(duì)于Swift協(xié)議犬绒,要實(shí)現(xiàn)可選協(xié)議可以在協(xié)議的extension中提供默認(rèn)實(shí)現(xiàn)旺入;還有一種方式就是使用如下oc兼容的方式:
@objc// 修飾后,swift中只有類凯力、協(xié)議能遵守這個(gè)協(xié)議茵瘾;OC中也能使用這個(gè)協(xié)議
protocol ZLOCprotocol {
// 1.這個(gè)方法是可選實(shí)現(xiàn)的,用optional修飾咐鹤,用了optional后拗秘,必須用@objc修飾
// 在swift的類中遵守協(xié)議實(shí)現(xiàn)下面方法不需要用@objc修飾
@objc optional func optionalFunc1()
// 這個(gè)方法在Swift中必須實(shí)現(xiàn)的,OC中是可選實(shí)現(xiàn)
// 不需要使用@objc修飾, 沒(méi)有用@objc也是可以在OC中使用
// 遵守協(xié)議后祈惶,如果是Swift中雕旨,不實(shí)現(xiàn)會(huì)報(bào)錯(cuò)扮匠;如果是OC中,不實(shí)現(xiàn)不會(huì)報(bào)錯(cuò)凡涩,運(yùn)行時(shí)調(diào)用方法時(shí)奔潰
func func2()
}
如果想要NSObject的類才能遵守棒搜,協(xié)議遵守NSObjectProtocol即可。