オブジェクト指向(PHP)

#オブジェクト指向とは

**オブジェクト指向**とは、システムの作り方の一種。
ちなみにシステムとは、個々の要素が相互に影響しあいながら全体として機能する纏まりのことであり、クラス同士を組み合わせて作られていくものである。

例えば、一つのシステムを構築するソースコードを、一つのクラス内に書こうと思えば全てを記載することが可能であるが、コードは冗長且つ複雑になるため可読性が低く、機能の変更や追加の必要性が生じた際に膨大な労力を生み出してしまうことが容易に想像できる。

そこで、役割ごとにクラスを作り分け、**『一つ一つのクラスを役割を持った物（オブジェクト）として扱おう』**として生み出されたのがオブジェクト指向である。

具体的に言うと、一つのパソコンには、キーボード、マウス、モニターなどの部品が存在する。

この部品にもそれぞれの役割があるように、役割を持った物ごとにクラスを作り分けておけば、キーボードが故障した際はキーボードクラスのソースコードを修正していけば良いし、新しい機能を付けたい時も対象となるクラスだけを変更すれば良いということである。

つまり、オブジェクト指向とは、**『ある役割を持った物ごとにクラスを分割し、物と物との関係性を定義していくことでシステムを作り上げようとするシステム構成の考え方』**であり、ソースコードの分け方の一種である。

##オブジェクト指向がもたらすメリット

オブジェクト指向は、大規模システムを作っていく上でメリットをもたらす。

前記の様に、機能の役割ごとにクラスやファイル等のソースコードを分けていくため、**一つのシステムを複数人で作成していくことが可能**である。

また、ソースコードを分けているため、短くまとまったコードは**可読性が高い上に、処理がシンプル**なのでテストも楽に実行出来る。

役割ごとに分けたクラスは、外部で必要になった際など**様々な場面で使い回すことが可能**である。
例えば、経理システム内で消費税計算のプログラムは様々な場面で使うことが予想出来るため、消費税計算の処理を一纏まりにしておけば、使い回しが可能になる。

そのクラス自体の作成意図が組めるため、**情報の管理がしやすい上、仕様の変更が生じても変更箇所の特定がし易い他、影響範囲も小さく、メンテナンス性が高い**というメリットがある。

故にオブジェクト指向を取り入れている言語は、大きいシステム構築で採用されるケースが多い。

##クラスについて
クラスは**設計図**とも言える。

例えば、車を作ろうとした時に、どんな機能が車にあるか想像してみると、車には色や持ち主等の固有情報を持つ他、加速・減速、ライトの点灯・消灯などの車として存在するために必要な機能が備わっている。

色や持ち主は変更が不可能ではないが、基本的には車が持つ固有の属性である。
アクセルを踏むと加速、ブレーキを踏めば減速する等の処理を担う機能のことをメソッドと呼ぶ。

こういった**物の情報と機能を定義したものがクラス**であり、まさにクラスはその物の設計図と言える。
よって、クラス内にはメソッドの定義と属性の宣言が出来る。

##インスタンスについて

前記の様に、クラスは紙一枚の設計図と一緒なので、紙一枚のクラス自体に処理を求めても不可能である。
そのため、設計図を元に処理を実行する実体を生む必要がある。

この設計図を元に生まれた実態を**インスタンス**と言い、**実体化することをインスタンス化**と言う。

いくら実態とは言え、インスタンス自体は動くことの出来ない、ただの物体に過ぎない。
そのため、実体化した物に対して、メソッドの呼び出し等の命令を与えていく必要がある。
（実体化した際に、自動的にインスタンスが処理を行う記述もクラス内に出来る）

設計図があれば、様々な個性ある車を作れる様に、一つのクラスからは複数のインスタンスを生成できる。
故にどんな車でも共通して持つ内容を設計図に定義する必要がある。

とはいえ、車の設計図のオーナー欄に『持ち主は太郎』と書いてしまうと、全ての車の持ち主が太郎として生成されてしまうため、初めから属性値を決めるような変数の初期化は宜しくない。

よって、属性のタイトルのみをクラスに定義し、各インスタンスに対してそれぞれの値を当てはめていくことが望ましい。

この理論で言えば、インスタンス化の後には、セットとして属性の値を詰めていく記述をする必要がある。
そこで、インスタンスというあやふやな存在を作りつつ、同時に値を詰めて完全な実体化をしていくことが理想であり、これをPHPでは**コンストラクタ**と呼ぶ。

コンストラクタを使用すれば、**インスタンスの生成時に自動的な処理をさせる**ことが出来る。

##カプセル化
オブジェクト指向には３つの重要な機能がある
その一つが**カプセル化**である。

例えば、人間クラスがあるとして、人間には名前という属性がある。
しかし、この名前は簡単に変更出来るわけではなく、意図して他人が変えれるものでもない上、SNS等に本名を上げてしまえば個人情報が拡散されるために隠したい情報でもある。

変更したい場合は本人が役所で手続きをする必要があり、**悪意による属性の書き換えや、うっかりミスや意図せぬ用途で外部クラスからの書き換えが出来ない様にする必要**がある。

また、車にはアクセルを踏むと前に進むという車としての揺るぎない機能がある。
これを変更してしまうと車としての存在意義を揺るがしてしまうことになるため、この機能をカプセルの内側に閉じ込めておこうというもの。

この目的を実現するためにカプセル化という存在がある。

カプセル化の機能の一つとして**アクセス権制御に係るprivate(プライベート)とpublic(パブリック)**がある。

**private**とは自クラス内からのみアクセスを許可するために付ける修飾子であり、プライベート化すると他人が知る由もない見えない存在になるため、**外部クラスからは変更はおろか参照も出来なくなる**。
**プロパティは基本的にアクセス権をprivateにすることが望ましい**。　



その反対で、**public**という修飾子を付けると、外部クラスからも参照や書き換えが可能となる。

publicを使用した場合

```php
<?php

  class Human {    //人間クラスを定義
    puclic $name  //氏名属性を定義してパブリック修飾子を付ける
    public function __construct($name) {
      $this->name = $name;
    }
  }
  //クラス外
  $japanese = new Human('taro');  //人間クラスをインスタンス（実体）化
  
  echo $japanese->name;  //japaneseインスタンス変数の氏名属性値を出力

  //出力結果：taro
?>
?>
```
privateを使用した場合

```php
<?php

  class Human {    //人間クラスを定義
    private $name  //氏名属性を定義してプライベート修飾子を付ける
    public function __construct($name) {
      $this->name = $name;
    }
  }
  //クラス外
  $japanese = new Human('taro');  //人間クラスをインスタンス（実体）化
  
  echo $japanese->name;  //japaneseインスタンス変数の氏名属性値を出力

  //出力結果：エラー
?>
```

###ゲッター

上記コードの様に、プロパティのアクセス権をprivateにすると、プロパティの値をクラスの外から取り出すことができなくなる。

そこで、プロパティの値を返すだけのメソッドの一つとして「**ゲッター**」が存在する。
ゲッターは**「getプロパティ名」**のように命名するのが一般的である。

```php
<?php
  class Human {   
    private $name  //プライベート修飾子を付けている
    public function __construct($name) {
      $this->name = $name;
    }
    public function getName() { //ゲッターを定義
      return $this->name;
    }
  }
  //クラス外
  $japanese = new Human('taro');   
  echo $japanese->getName();  //ゲッターの呼び出し
  
  //出力結果：taro
  
?>
```
###セッター

privateによりプロパティの値を変更出来ない場合に、プロパティの値を変更する**「セッター」**というメソッドが存在する。
セッターは**「setプロパティ名」**のように命名するのが一般的である。　


今回はここまで:santa: