プロトコル

プロトコルとは型が特定のプロパティやメソッドを持つために必要なインターフェースを定義するものである。プロトコルが要求するインターフェースを型が満たすことを準拠と呼ぶ。

定義方法と準拠方法

protocol User {
    func printName()
}

struct JapaneseUser : User {
    func printName() {
        print("中山です")
    }
}

// プロトコルUserに準拠しながら、メソッドprintName()を実装していないので、コンパイルエラーとなる。
struct ChineseUser : User {
}


protocol Nation {
    func printPassport()
}

// 構造体JapaneseUserにNationに準拠した処理を追加
extension JapaneseUser : Nation {
    func printPassport() {
        print("これがパスポートです")
    }
}
// 1つのextensionに対して、1つのプロトコルへの準拠が良い。どのextensionがどのプロトコルに準拠しているのかが、明確になる。

プロトコルの構成要素

  • プロパティ
    プロトコルのプロパティは常にvarで宣言し、{}の中にゲッターは必ず、また必要ならばセッターも追記する必要がある。
protocol User {
   // varで宣言、getは必須
   var name: String {get set}
}

//ゲッターの実装
protocol User {
    var name: String {get}
}

struct JapaneseUser : User {
    // varのまま
    var name: String
    func printName() {
        print("中山です")
    }
}

struct ChineseUser : User {
    // 定数にする
    let name: String
    func printName() {
        print("我叫李")
    }
}

struct UKUser : User {
    // コンピューテッドプロパティもOK
    var name: String {
        return "Tom"
    }
    func printName() {
        print("I am Tom")
    }
}

  • メソッド
    メソッドも定義できる。 メソッド名、引数の型、戻り値の型のみを定義する。またプロトコルでは実装しないので、{}は省く。
protocol User {
    var name: String {get}
    // {}は不要
    func instanceMethod() -> String
}

struct JapaneseUser : User {
    var name: String
    func instanceMethod() -> String {
        return "中山です"
    }
}