クラスの定義
クラスとは、オブジェクト指向プログラムにおいてオブジェクトを管理する最小のプログラムのことです。前章で作成した処理をクラスにまとめながらSwiftでのクラスについて学んでいきましょう。
オブジェクトを管理する
3.3 専門用語の節で Swift は処理の対象をオブジェクトで管理するオブジェクト指向のプログラム言語であることを説明しました。
このことは、言い換えるとオブジェクトとして管理できるものは全てSwiftで扱える、ことと同じです。
このオブジェクトを管理するプログラムの最小の単位がクラスです。クラスはオブジェクトの設計図とも呼ばれています。
つまりクラスというオブジェクトを管理する設計図で、プログラムで扱いたいものや処理を定義すれば、そのクラスを使って自由に処理をコントロールできる、ということになります。
これまでのサンプルでは、オブジェクトを管理するのはクラスではなく構造体(struct)でした。オブジェクト指向のプログラムではオブジェクトを管理する単位が共通してクラスであること、クラスと構造体の扱いの違いで実行結果に大きな違いが発生することはないことからここではオブジェクトを管理するプログラムとしてクラスを優先して説明します。
Swiftでは、構造体は比較的小さなデータを管理するために利用されます。7.2 ピッカー表示、8.4 JSONのパースで利用したように一定の意味を持ったデータを他と区別する入れ物のようなイメージで利用されることが多いです。
クラスを設計する例
「オブジェクトを管理する」と急に言われても、すぐにイメージするのは難しいかもしれません。
身近な例として猫をオブジェクトにする例を考えてみます。
オブジェクト指向プログラムでは、オブジェクトを管理するために性質と動作という2つの視点があります。猫オブジェクトを例にすると、次のものが挙げられます。
性質 | プロパティ名の例 |
種類 | kind |
性別 | gender |
年齢 | age |
動作 | メソッド名の例 |
食べる | eat |
寝る | sleep |
鳴く | mew |
性質に関しては属性や特徴、動作に関しては行動や操作と考えても構いません。
クラスでいうと、性質はプロパティ、動作はメソッドという書式で定義します。
このようにして性質や動作をプログラムで管理することで、オブジェクトとしてプログラムの中で猫を自在に操ることができる、というのがクラスの設計です。
クラスの書式
クラスを定義するときには、次の書式に従って定義します。
import フレームワーク class クラス名 [: プロトコル, スーパークラス] { var プロパティ1 var プロパティ2 init() { self.プロパティ1 = x self.プロパティ2 = y } func メソッド1() { // 処理 } }
最初にimport文で利用するフレームワークを指定します。「class クラス名」のブロックで、オブジェクトの状態を表すプロパティを変数として、オブジェクトを操作する内容をメソッドとして定義します。
クラスというオブジェクトの設計図から実際に生成されたオブジェクトをインスタンスと呼びます。
インスタンスを生成するときに実行するされるのが init メソッドです。initメソッドは特別なメソッドであり、「func」はつけずに定義します。
プロトコルを継承する場合はクラス名の後ろに「:」をつけてプロトコル名を記述します。
プロトコルを継承する場合は、プロトコルのルールに応じてプロパティやメソッドを記述する必要があることを覚えておいてください。
classブロックをstructブロックに変更すると構造体の定義となります。
クラスを作成する場合には、別のクラスの機能を継承してクラスを作成することもできます。機能が継承されるクラスをスーパークラス、機能を継承するクラスをサブクラスといいます。
スーパークラスの例 | サブクラスの例 |
class Animal { |
class Cat: Animal { |
サブクラスでは継承したスーパークラスのプロパティ、メソッドをクラス内に定義しなくても利用できます。スーパークラスの機能をそのまま継承して利用できると考えてください。
スーパークラス、サブクラスは高度なクラスを作成するとき以外はほぼ使いません。
スーパークラス、サブクラスの関係を継承関係や親子関係と呼ぶこともあります。
クラスを新規に作成するときに、手続き上出てくるので、こういう機能もあるということだけ覚えておいてください。構造体にはこのような継承関係はありません。
クラスを定義する
クラスを定義する例として、猫のオブジェクトを管理するCatクラスを定義してみます。
import Foundation class Cat { // 種類と年齢 var kind: String = "" var age: Int = 0 init () { self.kind = "" self.age = 0 } // 食べる func eat() { // 食べる処理 } // 寝る func sleep() { // 寝る処理 } }
最初にSwiftの基本的なフレームワークである「Foundation」をインポートします。
オブジェクトを管理するプロパティとメソッドを定義することで、自由にクラスを定義することができます。利用例は次のとおりです。
// インスタンスを生成して 種類と年齢を設定する例 let cat = Cat() cat.kind = "三毛猫" cat.age = 1
インスタンスを生成した後は、インスタンス名の後ろに「.(ドット)」でプロパティを記述することでプロパティにアクセスできます。上記の例では、種類と年齢のプロパティに値を設定しています。
種類と年齢をインスタンスの生成時に設定したい場合は、init メソッドの引数でプロパティを指定できるようにします。
クラス内でプロパティやメソッドを利用する時は、クラス自身のものであるという意味で「self.」をつけます。
init( age: Int, type: String) { self.age = age self.type = type }
インスタンスの生成はこのようにします。
let cat1 = Cat(age: 3, type: "マンチカン") let cat2 = Cat(age: 5, type: "ラグドール")
プロパティの最初の値や init メソッドでインスタンス生成時に設定する値のことを初期値と呼びます。
上記のようにインスタンス生成時に、プロパティの初期値を設定できるようにしておくと、インスタンスの生成時に詳細を指定できて便利です。