カレーを作りながらPHPオブジェクト指向プログラミングを学ぼう！！！

# はじめに
今回はphpの復習を兼ねてオブジェクト指向についてまとめたいと思います。また、直感的に理解しやすいように「カレーを作る」ということをテーマに進めて行きたいと思います。

# オブジェクト指向の３大要素
### 1.クラス
クラスには「まとめる」「隠す」「たくさん作る」という3つの特徴がある。
###### 1-1.「まとめる」とは
クラスには「プロパティ」や「関数」を含むことができる。カレーで例えると、「プロパティ」はカレーの具材であり、「関数」はそれらの具材を調理するといったところでしょうか。

```php:カレークラス
class Curry{
  public $carrot
  public $potatoes
  public $onion
  public $meet

  function cooking($carrot,$potatoes,$onion,$meet){
      echo "カレーの完成!具材は" . $carrot .$potatoes .$onion .$meet ."です。"
  }
}
```

```php:実行クラス
//Curryインスタンスを作成
$curry = new Curry();
$carrot = $curry->carrot = 'NINJIN’;
$potato = $curry->potatoes = 'JAGAIMO';
$onion = $curry->onion = 'TAMANEGI'
$meet = $curry->meet = 'GYUUNIKU';
$curry->cooking($carrot,$potatoes,$onion,$meet);
```
<p>カレーが作れましたね。ちなみに<strong>public</strong>は<strong>どこからもアクセス可能</strong>という意味があります。</p>

###### 1-2.「隠す」とは
先ほど作成したカレーは<strong>publicプロパティ</strong>にカレーの具材を代入しました。しかし、どこからでもアクセスできてしまうpublicのままだとカレーに意図しない具材が混入されてしまう可能性があります。

```php:実行クラス
//略
$meet = $curry->meet = 'BUTANIKU';
$curry->cooking($carrot,$potatoes,$onion,$meet);
```
なんということでしょうか、、、。肉が牛肉から豚肉になってしまいました。これでは<strong>「俺はビーフカレーしか食わねーんだよ！」</strong>という人が激怒してしまいますね。。。（知らんけど）
これを防ぐために<strong>カプセル化</strong>という外部からのアクセスを禁止し、内部に隠蔽する技術を使用する必要があるのです。


```php:カレークラス
class Curry{
  private$carrot
  private $potatoes
  private $onion
  private $meet
　　　　//略
}
```

publicはどこからも具材を混入し放題だったのに対し、<strong>privateは外部からの異物混入</strong>を遮断します。

```php:実行クラス（修正前）
$curry = new Curry();
//略
$meet = $curry->meet = 'GYUUNIKU';//エラー
```

では、privateの具材（プロパティ）に値の設定、取得をするにはどのようにすればよいのでしょうか。結論から述べると
<strong>Getter/Setter</strong>というメソッドを使用する必要があります。

```php:カレークラス
class Curry{
  //略
  private $meet
  //なんの肉を入れるか設定する。
  public function setMeet($meet){
     $this->meet = $meet;
  }
  //肉をゲットする。
  public function getMeet(){
     return $this->meet;
  }

}
```

```php:実行クラス（修正後）
$curry = new Curry();
//略
$curry->setMeet('GYUUNIKU');
$meet = $curry->getMeet();
```
Setter/Getterを使用してprivateの具材（プロパティ）の設定、取得ができました！
ただ、何回も具材を設定するのがめんどくさいと思うようなこともあるかもしれません。そんな時に使用するのが<strong>コンストラクタ</strong>となります。このコンストラクタは、Setterを使わずともインスタンス生成時にプロパティを設定することが可能になります。
※以下、具材を一部抜粋した例を表示

```php:カレークラス
class Curry{
  //略
  private $meet
  //他のプロパティは省略している、、、
  public function __construct($meet){
     $this->setMeet($meet);
  }

  //なんの肉を入れるか設定する。
  public function setMeet($meet){
     $this->meet = $meet;
  }
  //肉をゲットする。
  public function getMeet(){
     return $this->meet;
  }

}
```

```php:実行クラス（修正後）
//インスタンス生成時にmeetプロパティの設定
$curry = new Curry('GYUUNIKU');
//略
//セッターを使用していたパターン
//$curry->setMeet('GYUUNIKU');
$meet = $curry->getMeet();
```
上記のようにコンストラクタを使用すると、Setterを書く回数を減らすことができます。

###### 1-3.「たくさん作る」とは
これに関しては、直感的に理解しやすいと思います。要するに「カレー量産しようぜ！！！」って感じです。

```php:実行クラス（修正後）
//1日目用のカレー
$curry = new Curry();
//2日目用のカレー
$curry2 = new Curry();
//３日目用のカレー
$curry3 = new Curry();
//略
```
<strong>じゃじゃーん！なんと、たった1つのカレークラスから3日分のカレーを作れるのです！！！</strong>


### 2.継承
継承はクラスの共通部分を別のクラスにまとめる仕組みである。コードを再利用することができるというメリットがあります。以下カレークラスを継承しインドカレー、タイカレーのクラスを作成してみます。

```php:カレークラス（継承元）
class Curry{
  private $meet
  //他のプロパティは省略している、、、
  public function __construct($meet){
     $this->setMeet($meet);
  }

  //なんの肉を入れるか設定する。
  public function setMeet($meet){
     $this->meet = $meet;
  }
  //肉をゲットする。
  public function getMeet(){
     return $this->meet;
  }

  function cooking($carrot,$potatoes,$onion,$meet){
      echo "カレーの完成!具材は" . $carrot .$potatoes .$onion .$meet ."です。"
  }
}
```

```php:インドカレークラス
class IndianCurry extends Curry{
  //
}
```

```php:タイカレークラス
class ThaiCurry extends Curry{
  //
}
```

```php:実行クラス（修正後）
//カレー
$curry = new Curry();
$curry->cooking('略');
//インドカレー
$curry2 = new IndianCurry();
$curry2->cooking('略');
//タイカレー
$curry3 = new ThaiCurry();
$curry3->cooking('略');
//略
```
継承したインドカレー、タイカレークラスでは、カレークラスのプロパティとメソッドを再利用することができます。




### 3.ポリモーフィズム
ポリモーフィズムとは日本語で「多態性」「多相性」と訳され、いろいろな形に変わるという意味を持っています。

```php:カレーを食べる人クラス
class CurryEater{
  //略
  /*インド、タイカレーの親クラス（継承元）が引数
  なので、どちらのクラスも引数に指定可能。
  */
  public function EatCurry(Curry curry){
     $currry = curry.cooking();
     echo "" . $curry . "私はそれを食べました。";
  }
}
```

```php:カレークラス（継承元）
class Curry{
  private $meet
  //他のプロパティは省略している、、、
  public function __construct($meet){
     $this->setMeet($meet);
  }

  //なんの肉を入れるか設定する。
  public function setMeet($meet){
     $this->meet = $meet;
  }
  //肉をゲットする。
  public function getMeet(){
     return $this->meet;
  }

  function cooking($carrot,$potatoes,$onion,$meet){
      echo "カレーの完成!具材は" . $carrot .$potatoes .$onion .$meet ."です。"
  }
}
```

```php:インドカレークラス
class IndianCurry extends Curry{
  //
}
```

```php:タイカレークラス
class ThaiCurry extends Curry{
  //
}
```

```php:実行クラス
//カレー
$curry = new Curry();
//インドカレー
$curry2 = new IndianCurry();
//タイカレー
$curry3 = new ThaiCurry();
//カレーを食うヤツ
$eater = CurryEater();
$eater->EatCurry(curry2);
$eater->EatCurry(curry3);
```
1つのメソッドからインドカレーもタイカレーも食べることができましたね。このようにポリモーフィズムは呼び出しがわのメソッドを共通化することができるということがわかります。1つのメソッドがいろいろな形に変化するのですね！

# 最後に
最後までこの記事を読んでいただきありがとうございました。オブジェクト指向という言葉はこの業界にいるとよく聞きますが、完全に理解するのはとても難しい気がします、、、笑　今後はデザインパターンなども学習していけるといいですね。

ps.私はこの記事が記念すべきqiita初投稿でした！これからも学んだことをアウトプットしていければなと思います。



この記事は以下の情報を参考にして執筆しました。

- [オブジェクト指向でなぜ作るのか](https://www.amazon.co.jp/dp/B092HDFJKK/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
- [PHPオブジェクト指向入門（前半）](https://qiita.com/mpyw/items/41230bec5c02142ae691)