Swift5.1 - 協(xié)議(10)

協(xié)議(Protocol)

  • 使用 protocol 關(guān)鍵字來(lái)定義一個(gè)協(xié)議;
  • 協(xié)議可以用來(lái)定義方法屬性、下標(biāo)聲明;
  • 協(xié)議可以被枚舉、結(jié)構(gòu)體類(lèi)遵守;
  • 多個(gè)協(xié)議之間可以用逗號(hào)隔開(kāi);
protocol Behaviour {
    func run()
    var age: Int { set get }
    var height: Int {get}
    subscript(index: Int) -> Int { get set}
}
protocol Behaviour1 {}
protocol Behaviour2 {}
protocol Behaviour3 {}

class Animal: Behaviour1, Behaviour2, Behaviour3 {
    
}
  • 協(xié)議中定義的方法不能有默認(rèn)參數(shù)值;
  • 協(xié)議中定義的內(nèi)容,默認(rèn)必須全部實(shí)現(xiàn);

協(xié)議的屬性

  • 協(xié)議中定義的屬性必須都為 var 屬性,let 屬性將會(huì)報(bào)錯(cuò);
  • 實(shí)現(xiàn)協(xié)議的屬性權(quán)限,不小于協(xié)議中定義的屬性權(quán)限;
    1. 如果定義了 get 屬性,實(shí)現(xiàn)協(xié)議時(shí),可以實(shí)現(xiàn)為 getget & set的計(jì)算屬性;
    2. 如果定義了 get & set 屬性,那么只能實(shí)現(xiàn)為get & set 的計(jì)算屬性;

static 、class

  • 為了保證通用,協(xié)議中必須用static定義類(lèi)型方法、類(lèi)型屬性、類(lèi)型下標(biāo);
    1. 因?yàn)槊杜e和結(jié)構(gòu)體不能用 class;
protocol Behaviour {
    static var height: Int {get}
}

class Animal: Behaviour {
    class var height: Int {
        return 10
    }
}

mutating

  • 只有將協(xié)議中的 實(shí)例方法 標(biāo)記為mutating;
    1. 才能允許結(jié)構(gòu)體、枚舉的具體實(shí)現(xiàn)修改自身的內(nèi)存
    2. 類(lèi)在實(shí)現(xiàn)方法時(shí)不用加 mutating 關(guān)鍵字,枚舉、結(jié)構(gòu)體需要加mutating(swift5.1好像已經(jīng)不用加了);
protocol Behaviour {
    mutating func run()
}

struct Animal: Behaviour {
    func run() {
        
    }
}

init

  • 協(xié)議還可以聲明初始化方法 init;非 final 類(lèi)實(shí)現(xiàn)該初始化器必須加 require 關(guān)鍵字,final 類(lèi)實(shí)現(xiàn)該初始化器可以不加 require 關(guān)鍵字;
protocol Behaviour {
    init(age: Int, name: String)
}

class Animal: Behaviour {
    required init(age: Int, name: String) {
        // ...
    }
}

final class Person: Behaviour {
    init(age: Int, name: String) {
        // ...
    }
}
  • 假如實(shí)現(xiàn)的協(xié)議方法的初始化器,正是重寫(xiě)父類(lèi)的指定初始化器,那么這個(gè)初始化器方法必須同時(shí)加 require 、 override 關(guān)鍵字;
  • 協(xié)議中定義的 init?、init!,可以用 initinit?、init! 去實(shí)現(xiàn);
  • 協(xié)議中定義的 init,可以用 init、init! 去實(shí)現(xiàn);

協(xié)議的繼承

  • 一個(gè)協(xié)議可以繼承其他協(xié)議的方法,屬性,下標(biāo);
protocol Behaviour {
    func run()
    subscript(index: Int) -> Int {get}
}

protocol SubBehaviour: Behaviour {
    func eat()
}

class Animal: SubBehaviour {
    subscript(index: Int) -> Int {
        return 10
    }
    
    func eat() {
        //...
    }
    
    func run() {
        //...
    }
}

協(xié)議的組合

  • 協(xié)議組合可以包含最多1個(gè)類(lèi)類(lèi)型;
protocol Drawable {}
protocol Runnable {}
class Person {}

// 接收Person或其子類(lèi)的實(shí)例
func test1(obj: Person) {}

// 接收遵守Drawable協(xié)議的實(shí)例
func test2(obj: Drawable) {}

// 接收遵守 Drawable與Runnable 協(xié)議的實(shí)例
func test3(obj: Drawable & Runnable) {}

// 接收遵守 Drawable與Runnable 協(xié)議,并且是Person或其子類(lèi)的實(shí)例
func test4(obj: Person & Drawable & Runnable) {}

CaseIterable

  • 讓枚舉遵守 CaseIterable 協(xié)議,可以實(shí)現(xiàn)枚舉遍歷;
enum Test : CaseIterable {
    case a, b, c, d
}

let cases = Test.allCases
print(cases.count)  // 4
for c in cases {
    print(c)
}  // a、b、c、d
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容