【Swift】クラスの使い方。オブジェクト指向プログラミングとインスタンスについて(Swift 2.1、XCode 7.2)

2020年6月16日

オブジェクト指向プログラミングとは

Swiftはオブジェクト指向言語である。オブジェクトとは、役割ごとに分けたデータ操作の集まりのことをいう。

例えば、ハンバーガーショップでイメージしてみると、店員は「社員番号、名前、担当作業」などのデータを持ち、「注文を受ける」などの操作を持ったオブジェクト。店員は複数人いるので、社員番号、名前が異なる店員オブジェクトが沢山いる。

レジは「レジ内現金、注文受付商品、在庫情報」などのデータを持ち、「注文をキッチンに送信」などの操作を持ったオブジェクト。

オブジェクトは他のオブジェクトからの要求に対して、自分が持っているデータを使ったり、さらに他のオブジェクトから情報を貰ったりして要求に答える。例えば、店員オブジェクトはバリューセットの注文を受けると、レジオブジェクトに対して自分の社員番号、商品情報を引数に「注文をキッチンに送信」を要求する。

要求を受けたレジオブジェクトは品切れ情報を確認、受付担当者を保存して、キッチンオブジェクトに対して注文情報を引数に調理を要求する。要求を受けたキッチンオブジェクトはバリューセットオブジェクトを作り、レジオブジェクトに戻す。

オブジェクト指向の例

 

このように、オブジェクトたちが互いに要求を投げ合いながら、プログラムを構成する手法をオブジェクト指向プログラミングという。

クラスとは

クラスとは、このオブジェクト指向プログラミングを実現するために、プロパティ(データ)とメソッド(操作)を集めて1つにまとめたコードのことをいう。

ただし、クラスはインスタンスというものを生成して始めてオブジェクトの役割を担うことができる。言わば、クラスは設計図、インスタンスは設計図をもとに作られた実体のようなものである。1つのクラスから複数のインスタンスを作ることができ、インスタンスごとに社員番号、名前が違う店員オブジェクトが複数いたり、ハンバーガーの種類やポテトのサイズが違うハンバーガーオブジェクトが複数いたりする。

クラス説明

 

クラスの作り方

クラスは以下のように定義する。

 

上記例の社員クラスを実装すると以下のコードのようになる。しかし、以下のコードはコンパイルエラーになる。なぜなら、社員番号、名前、担当に値が設定されていないためである。Swift2.0においては、クラスのプロパティは必ず初期値を設定しなければならない。

そこで、以下のコードのようにプロパティの宣言と同時に値を設定すればエラーは発生しなくなる。社員番号、名前、担当はインスタンスごとに値を変える必要があるので、未設定を意味するような値を設定しておく。

 

インスタンスの作り方

次にクラスからインスタンスを生成する。「var 変数 = クラス名()」のように記述することでインスタンスが変数に代入される。そして「変数.プロパティ名 = 値」で社員番号、佐藤、ホールスタッフの値を設定する。これでインスタンスごとに異なるプロパティ値を持たせることができた。

 

しかし、この方法はあまり好ましくない。理由は、プロパティ値を初期化するために何行も記述するのが煩わしいというのもあるが、初期化後に変更しない値を変数(var)で宣言しなければならないため、プロパティ値が思わぬところで変更されないよう今後のコーディングで注意する必要が出てくるためだ。

そこで、利用するのがイニシャライザというメソッドである。イニシャライザとは、インスタンスを生成するときに呼び出されるinitメソッドのことである。イニシャライザの中でプロパティ値を設定すれば、プロパティを宣言すると同時に値を代入しなくても良くなる。

例えば、以下のコードのように、init(社員番号, 名前, 担当)というメソッドを定義しておけば、社員クラスのインスタンスを生成するときに必ず社員番号, 名前, 担当を引数に与えることになる。

これにより、インスタンス生成のコードがスッキリするのと同時に、プロパティを定数(let)で宣言して安全性を高めることができるということだ。

 

イニシャライザを複数定義する

イニシャライザは引数を変えて複数定義できる。

例えば、先ほどの引数が3つのイニシャライザの下に、引数が2つのイニシャライザを定義したのが以下のコードである。担当を設定する必要が無い場合に2つの引数でインスタンス生成することができる。なお、イニシャライザの中から別のイニシャライザを呼ぶ場合はinitの頭にconvenienceを付ける必要がある。

 

ちなみに、以下のコードのように引数が与えられなかったときの初期値を記述しておけば、引数2つ、3つどちらでもインスタンス生成できるので、イニシャライザを複数用意する必要は無くなる。

 

レジクラスを作ると以下のコードのようになる。オブジェクトから別のオブジェクトのメソッドを呼び出すイメージをつかむのが目的なので、プロパティの使われ方やメソッド内の処理については省略している。

 

社員オブジェクトからレジオブジェクトのメソッドを呼び出すので、社員オブジェクトにレジオブジェクトの参照を持たせるように修正する。

 

社員のインスタンスを生成するときにレジのインスタンスを引数に与える。これで、社員インスタンスからレジインスタンスのメソッドを呼び出せるようになった。