Swift 協定 (Protocols)

協定 (Protocol) 定義了執行某項任務或功能所需的藍圖 (Blueprint)。類別、結構或列舉之後可以遵循 (Adopt) 這些協定來實作具體功能。

這類似於 Java 中的 Interface,但功能更強大。

定義協定

protocol SomeProtocol {
    // 定義屬性 (只說明讀寫權限,不給初始值)
    var mustBeSettable: Int { get set }
    var doesNotNeedToBeSettable: Int { get }
    
    // 定義方法
    func someMethod()
}

遵循協定

struct SomeStructure: SomeProtocol {
    var mustBeSettable: Int
    let doesNotNeedToBeSettable: Int // 因為協議只要求 get,所以 let 也可以滿足 (唯讀)
    
    func someMethod() {
        print("實作了這個方法")
    }
}

代理模式 (Delegation)

Protocol 最常見的應用之一是代理模式 (Delegate Pattern)。這是 iOS 開發中極為常用的設計模式,用於物件溝通。

例如,定義一個「骰子遊戲代理」:

protocol DiceGameDelegate: AnyObject {
    func gameDidStart(_ game: DiceGame)
    func game(_ game: DiceGame, didEndTurnWithDiceRoll diceRoll: Int)
}

這裡繼承 AnyObject 表示這個協議只能被 Class 遵循 (因為之後通常會用 weak 變數來持有它,避免循環參考)。

協定擴展 (Protocol Extensions)

這是 Swift 最強大的特性之一。你可以為 Protocol 提供預設實作

這意味著你可以通過擴展 Protocol 來為所有遵循該 Protocol 的型別添加功能,而不需要繼承。這是「面向協議編程 (Protocol-Oriented Programming, POP)」的核心。

protocol RandomNumberGenerator {
    func random() -> Double
}

extension RandomNumberGenerator {
    // 為 random() 提供預設實作
    func random() -> Double {
        return Double.random(in: 0.0...1.0)
    }
}