前言
在上一篇文章中,大抵提到了協定的基本概念與功用,本篇接著會提到的是協定作為是型別的作用,本篇會是一篇較為複雜的一篇,因為協定在例證中會因為原先的協定內容傳入類別中,又經過實體化,而回去查找原先類別中的屬性與方法所含有的概念。
但這是協定作為參數傳入後,釐清協定之運作方法,故,本篇以兩部分為主要內容:
- 協定作為參數傳入
- 委任模式
正文
協定作為參數傳入
協定本身沒有實作任何功能,但協定仍可以被當做一種型別來使用。使用情況就如同一般型別一樣,如下:
作為函式、方法或建構器的參數型別或返回值型別。
作為常數、變數或屬性的型別。
作為陣列、字典或其他集合中的元素型別。
那幾乎…..就是所有的型別都可以被協定統包?所以只要說我是協定,我就可以讓所有人都接納我?
如以下實例:

- 1–3行的部分我們先做了個基本的協定
- 5–9行的部分,則將一個類別Important引入協定,並設定了依據協定的函式
- 另起一個類別,其中建構了一個常數,其中型別是協定,並用建構器建構化這個參數。也就是說,這個建構器的參數所接受的值是協定
- 19行實體化Important類別,20行實體化AnotherClass類別,並傳入參數為important,是為Important的實體化產物
- 最後這一段要有一個概念:遵循協定的實體,都可以被當作是協定型別,所以important內含協定,是可以被傳入的
- 21行則以another實體,呼叫常數somethingProtocol,然後在呼叫someFunction( )
總之,上面有一個很重要的概念:任何遵循一個協定的實體,都可以被當做這個協定型別的值。
寫到這裡突然覺得協定很OP,無孔不入的感覺。
委任模式
委任(
delegation
)是一種設計模式,它允許類別或結構將一些需要它們負責的功能委任給其他型別的實體。委任模式的實作就是定義協定來封裝那些需要被委任的功能,而遵循這個協定的型別就能提供這些功能。委任模式可以用來回應特定的動作或是接收外部資料,而不需要知道外部資料的型別。
不過,或許以實際案例來舉例,會比較容易清楚說明:
1.先把協定設定好

2.賦予類別協定
因此,在GameCharacter背後具有兩件事情:
一件是delegate屬性被指為GameCharacterProtocolDelegate,且設為nil
一件是attack( )方法中含有兩件事:
其一為print(“攻擊”),
其二為調用變數中的被指向為協定的GameCharacterProtocolDelegate底下所具有的didAttackDelegate( )

3.接著類別GameCharacterDelegate指向GameCharacterProtocolDelegate的協定,補充在它下面的函式

4.接著是實體化, 一個實體將.delegate的部分指為charDelegate,一個讓它執行呼叫後的動作,遊戲實體呼叫攻擊。

在這裏,onechar.delegate指向的會是(圖一)在10行裡的nil,charDelegate則包含的是(圖二)方法 func didAttackDelegate的內容,會打印出“攻擊後的整理工作”


所以,這個時候我們再回來看最後:
func attack( )容納了print(“攻擊”),下面一行再加上delegate被指為類型GameCharaterDelegate,這個變成了實體,而不再是nil,因此要呼叫didAttackDelegate( )也會成立。

最後,呼叫attack( )就會變成是兩行:

結果:

我們再回來看一下委任模式的解說:
委任(
delegation
)是一種設計模式,它允許類別或結構將一些需要它們負責的功能委任給其他型別的實體。委任模式的實作就是定義協定來封裝那些需要被委任的功能,而遵循這個協定的型別就能提供這些功能。委任模式可以用來回應特定的動作或是接收外部資料,而不需要知道外部資料的型別。
大概可以藉此知道,委任模式是基於協定可以作為參數的這個特性,因此而能將其含有協定的實體放入類別下的參數中。
不過,協定還有很多不同的功能,大概沒辦法在這個短篇幅裡全部交代完,還需篇幅說明。