Swift 入門 | プロトコルと拡張 | プロトコル

Swift では、オブジェクトが持つメソッドを呼び出して処理を行う。オブジェクトを扱うには、どのようなメソッドが用意されているかを知る必要がある。

継承関係のない複数のクラスをまとめて処理する場合、すべてに共通のメソッドがあると便利である。しかし、共通のスーパークラスがなければ、そのメソッドが必ず存在することを保証できない。

この問題を解決するものがプロトコルである。プロトコルは、プロパティとメソッドの宣言だけを持つクラスのようなものである。

protocol プロトコル名 {
    ... プロパティとメソッドの宣言 ...
}

メソッドには実装部分を記述せず、必要なシグネチャだけを宣言する。

クラスでプロトコルを採用する構文は、継承と似ている。

class クラス名 : プロトコル名 {...}

スーパークラスも継承する場合は、スーパークラスを先に書き、プロトコルをコンマで区切る。複数のプロトコルを採用することもできる。

プロトコルを採用したクラスは、そのプロトコルが要求するすべての機能を実装する必要がある。実装しなければコンパイルエラーになる。これにより、プロトコルに準拠するすべてのクラスが必要なメソッドを持つことを保証できる。

次の例ではプロトコルを定義して使用する。

protocol MyProtocol {
    func printData ()
}

class PersonData: MyProtocol {
    var name:String = ""

    init(name:String) {
        self.name = name
    }

    func printData() {
        print("[name: \(name).]")
    }
}

class MemoData: MyProtocol {
    var content:String = ""

    init(content:String) {
        self.content = content
    }

    func printData() {
        print(content)
    }
}

var data:[MyProtocol] = []
data.append(PersonData(name: "kimkc"))
data.append(MemoData(content: "午前 9 時から会議"))
for obj in data {
    obj.printData()
}

MyProtocolprintData メソッドを要求する。PersonDataMemoData は継承関係がなく、異なるプロパティを持つが、どちらもプロトコルを採用している。

data 配列は値を MyProtocol 型として保存する。MyProtocol に準拠するクラスのインスタンスであれば追加できる。ループではプロトコル型を通じて printData を呼び出す。

プロトコルを使うと、継承関係のないクラスを共通のインターフェースでまとめて処理できる。