【Swift】プロトコルの使い方。クラスに実装しなけれならないプロパティ、メソッドを指定する。(Swift 2.1、XCode 7.2)

2020年6月16日

プロトコルとは

プロトコルとは、クラスに実装するプロパティとメソッドを指定する機能である。他言語ではインタフェースなどと呼ばれている。プロトコルを適用したクラスはプロトコルに定義されているプロパティとメソッドを必ず実装しなければならない。

プロトコルが役に立つ例を一つ挙げる。

例えば、プログラム開発をAチームとBチームで分担して行い、 Aチームはメンバー管理クラス、Bチームは会員クラスを作ることになった。メンバー管理クラスで会員クラスのインスタンスを生成してメソッドを呼び出すが、Bチームはまだ会員クラスを作り始めていなく、作成するプロパティやメソッドも確定していない。

そんなときは、メンバー管理クラスが利用するプロパティとメソッドを列挙したプロトコルをAチームが作成してBチームに渡す。これでBチームが会員クラスを作るときにメンバー管理クラスが必要なものが実装されることが保証された。

AチームはBチームの会員クラスが完成するまでは、プロトコルを適用した空の会員クラスを利用しながらメンバー管理クラスを作る。

プロトコルの利用例

 

プロトコルを定義する

プロトコルは以下のように定義する。プロパティ名の横には{ get, set }または{ get }を記述する。{ get, set }は読み書き可能、{ get }は読み込みのみを意味している。{ set }は定義できない。

 

以下は会員クラス用のプロトコルを定義し、それを適用した会員クラスを作成したコードである。プロトコルを適用するときは、クラス宣言で「クラス名:プロトコル名」と記述する。プロトコルに定義されていないプロパティやメソッドも自由に記述することができる。

例では、プロトコルの定義で総合ポイント(totalPoint)を読み込みのみにしたが、変数(var)で実装してもエラーにならず、値も変更できるのが不思議だ。

 

ちなみに、統合ポイントはプロトコルでvar(変数)で宣言されているが、実装するときに定数(let)にできる。逆に、{ get set }で定義した場合は、定数(let)で実装しようとするとエラーになる。

 

クラスの継承は1つのクラスにつき1個しか継承できないが、プロトコルは1つのクラスに複数のプロトコルを適用できる。クラス宣言で「クラス名:プロトコル名, プロトコル名, プロトコル名,..」のようにカンマで区切りながら定義する。

以下のコードは3個のプロトコルを1つのクラスに適用する例。

プロトコルを継承する

プロトコルを継承したプロトコルを作成することができる。プロトコルの宣言で「プロトコル名:スーパープロトコル名,スーパープロトコル名, …」と記述する。クラスの継承の制限「1クラスで継承できるクラスは1個まで」が無いのがクラスと異なる。

上記コードと同じ機能をプロトコルの継承で実現したのが以下のコードである。

 

クラスを継承したクラスにプロトコルを適用するには、クラス宣言で「クラス名:スーパークラス名, プロトコル名,プロトコル名, …」と定義する。必ずプロトコル名より前にスーパークラス名を記述すること。

 

Enum(列挙型)や構造体にプロトコルを適用する

プロトコルは、クラスだけではなくEnum(列挙型)や構造体にも適用することができる。以下のコードはEnumにプロトコルを適用する例。

 

以下のコードは構造体にプロトコルを適用する例。