[Swift 3] Protocol

部分內容筆記。

Protocol作為Type

Protocol作為type,可以當作collection宣告的一部分,也可以作為變數宣告的一部分,用來表示該變數不論是什麼類別,但必定遵守此protocol,另外也可以用down cast的語法來處理它。

Optional Protocol Requirements

你可以為protocol定義Optional requirements。遵守此protocol的type不用一定要實作這些Optional requirements。Optional requirements的定義方法是在protocol的宣告前面加上optional的前綴修飾詞。

使用上,當你的protocol裡面的member為Optional requirements時,該member前面要加上@objc,並且該protocol的宣告前面也要加上@objc。
@objc protocol SomeProtocol {
@objc optional func someMethod()
}

需要注意的是,這代表這些properties和methods的type都是optional。因為你可以不實作,那表示這值可能就是nil,methods也有type,由參數和回傳值組成,例如(Int) -> String,這時就會變成 ((Int) -> String)?

@objc protocol SomeProtocol {
@objc optional var storedProperty: Int {get}
@objc optional func someFunction() -> String
}

加上optional表示有沒有實作都可以,所以使用上要配合optional chain,如果是optional function,要在呼叫時,於括號前加上問號。

if let text = adoptedClassInstance.someFunction?() {
print(text)
}

加上@objc表示要和objective-C協作,protocol前面也需要註記@objc。這樣的protocol只能由繼承自objective-C或是其他@objc的類別遵守。無法由structure或是enumeration來遵守。

@objc class SomeClass : SomeProtocol {
}

Protocol Extensions

Protocols可以藉由擴展(extend)提供方法和屬性的實作給遵守它的types。藉由擴展,讓你可以定義protocol的行為,而不必在每一個遵守該Protocol的type或是在global函數裡面去實作這些行為。

這裡稍微和你直覺想像的protocol的extension不同,protocol的extension是可以提供具體的實作的,你可以想像這個extension是將所有adopt某個extended protocol的class都外加一些properties或是methods。可以說是對全部conformed to this extended protocol的class的extended。

extension SomeProtocol {
fun description() {
print(someFunction())
}
}

到這邊你可以想像說,那extension可不可以讓protocol的required的properties或是methods有預設的實作呢?當然可以,在conforming type提供自己的實作之後,預設的實作就會被替代掉,反之,conforming type沒有提供需要的實作的話,就會採用預設的實作。

Adding Constraints to Protocol Extensions

你可能不希望extended protocol可以適用所有conforming type,你可以加上一些限制,以便在讓那些conforming type取得extended protocol裡面定義的實作之前,進行檢查。你會使用where這個generic clause(參考這裡)。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.