Open5

オブジェクト指向

oskmroskmr

オブジェクト指向とは「モノに注目すること」

オブジェクト指向において全てのものはオブジェクトとして表現される
全てのオブジェクトは状態(プロパティ)と振る舞い(メソッド)をもつ

車で例えると,
車そのものがオブジェクト
それを構成するハンドルやタイヤなどのものもオブジェクト
タイヤの空気圧, 給油タンクならガゾリンの量が状態(プロパティ)
ハンドルを回す, タイヤが回ることが振る舞い(メソッド)

オブジェクトが全て組み合わさることで車(製品)ができる

タイヤがパンクした時はタイヤだけ取り替えればいいように、バグや変更の際に修正が必要なオブジェクトに対してだけ修正を行えばいい

oskmroskmr

クラス

オブジェクトをモデリングするには、そのオブジェクトの状態(プロパティ)と振る舞い(メソッド)の仕様を設計(定義)しなければいけない
-> オブジェクトの設計書がクラス

インスタンス

定義されたクラスをもとに実際に作られたオブジェクトがインスタンス
インスタンスがクラスに対する具体的な概念

例えば、クラスがロボットの設計書で実際に作られたロボットがインスタンス
クラスは一つしかないけど、インスタンスはロボットが大量生成されるように複数になる
インスタンスごとに状態をもつことができる

クラス定義

クラスはオブジェクト=インスタンスの設計書
インスタンスの状態(プロパティ)および振る舞い(メソッド)をコードで定義する

class クラス名 {
   プロパティ宣言
   メソッド宣言
}

プロパティとメソッド

インスタンスは状態(プロパティ)か振る舞い(メソッド)をもつ
例えばロボットクラスは「消費電力、パワー、速度」などのプロパティ、「歩く、つかむ」などのメソッドを持つ
プロパティは一度設定したら変更できない読み取り専用のletと変更が可能なvarという*予約後を用いて宣言する
メソッドの場合はfuncという予約後を用いて宣言する

class Robot {
    // プロパティ
    let name : String = "まるえもん" 
    var power : Int = 100

    // メソッド
    func say() -> () {
         print("僕、\(name), 戦闘力は \(power) です。") }
}

インスタンスの初期化・プロパティにアクセス・メソッドの実行

設計書を書いただけでは動かないように、クラス定義を書いただけでは何も起こらない
設計書をもとに実際の製品を製造する必要がある
実際の製品を製造するように、クラス定義から実際のインスタンスを生成することをインスタンスの初期化という
インスタンスを以下の世に生成し、メソッドを実装する

let 定数名 = クラス名 ()
インスタンス. メソッド ()

プロパティへのアクセスも同じように出来る

インスタンス. プロパティ

*プログラムを制御する際に必要な単語を予約語と言う。cf.( if , for .. )

oskmroskmr

継承

オブジェクト指向4つの柱

  • クラス
  • 継承
  • カプセル化
  • 多様態(ポリモーフィズム)

クラスがオブジェクト指向プログラミングの土台で、その上に残りの3本の柱が立っているとも言われている
クラス以外でオブジェクト指向プログラミングを最も強力にしているのが継承

継承とは文字通り引き継ぐこと
オブジェクト指向ではプロパティとメソッドを引き継ぐ
BクラスがAクラスを継承するとき、BはAが持っていたプロパティとメソッドを引き継ぐ
継承元のAクラスを「親クラス, 基底クラス, スーパークラス」、継承先のBクラスを「子クラス, サブクラス」とも呼ぶ

class サブクラス : スーパークラス { 
   サブクラスにて追加・変更するプロパティ 
   サブクラスにて追加・変更するメソッド
}

一つのクラスは直接継承できるクラスが一つに制限されている
もし、継承したスーパークラスが他のクラスを継承している場合はスーパークラスのスーパークラスも継承したことになる

メソッドのオーバーライド

スーパークラスのメソッドに対して変更or追加をしたいとき、スーパークラスと同じ名前のメソッドをサブクラスに定義するとできるようになる
これをメソッドのオーバーライドという
オーバーライドをするメソッドを定義するときは、先頭にoverrideという予約後をつける必要がある
superでスーパークラスのメソッドを呼ばなければ同じ名前のメソッドを作ることができる

oskmroskmr

継承のメリット・デメリット

メリット

継承を使うと何が嬉しいのか

  • コードに冗長性がなくなり短くなる
    • 共通部分を継承元のクラスにまとめることができる
  • コードの拡張性が高くなる
    • 新しい機能追加などをする時に、元のあるクラスを継承すればコスト低く拡張できる
    • コードのメンテナンス性が高くなる
      • 継承元のクラスに変更を加えれば、そのクラスを継承した全てのクラスにその変更が適用されるのでコスト低くメンテナンスができる

デメリット

大規模なプログラムの場合継承が深くなり過ぎて、逆にコードが分かりづらくなる
-> 解消する方法としてプロトコル思考プログラミングが提唱された

oskmroskmr

継承と汎化

継承の反対の表現で汎化がある
継承は上から下、スーパークラスからサブクラスをつくるという流れ
汎化はたくさんのクラスから共通部分を見つけ出してスーパークラスにするという下から上への流れ
オブジェクト指向設計の段階で汎化によって作成されたクラスをスーパークラスにすることが、プログラミングの段階で継承になる

例えば

  • スーパーカークラス
  • パトカークラス
  • タクシークラス
    というクラスがある

この3つのクラスのプロパティとメソッドを見るとname, numberプロパティとaccelerate()メソッドが共通しているので、
3つのクラスに共通するプロパティとメソッドをまとめたCarクラスを定義する

この具体的なクラスの共通部分をまとめて 1 つのクラスにすることが汎化