【PHP】オブジェクト指向を使って初めて動くものを作った

<br>
こんにちは、Reikaです。<br>私は現在、アプレンティスの5期生として日々勉強に励んでいます。<br>

https://apprentice.jp/lp

アプレンティスの課題としてオブジェクト指向の実装に取り組みました。<br>今回はこの経験を通じて学んだことについて、記述していきます。<br>

# 今回のお題
早速ですが、今回は以下のトランプの戦争ゲームの実装を目指しました。<br>
#### 大まかなルール
・プレイヤーがカードを出し合い、カードの数の大小を比べる。
・強いカードを出したほうが勝ちとなり、相手のカードを含めカードをもらう。
・このようにして続けていき、誰かの手札がなくなったら終了。最後に多くカードを持っていた人が勝ちになる。

<br>
最初は要件を見て、めちゃめちゃ不安でした。コードのイメージが湧きませんでした。<br>ですが、今から記述する<font color="red">オブジェクト指向の三つの重要概念</font>を押さえたら理解も早く済みました！<br>ではでは、私が学んだ知識をご説明します。

# オブジェクト指向とは？
まずは、そもそもオブジェクト指向って何？というところから。<br>ざっくり言うと、**全てを物（object）として考えて設計する方法**です。
例えば今回のトランプゲームで言えば、**プレイヤーとカード**が物。
また、**ゲームや判定のルール**といった人や物以外の概念等も、物として考えます。
それらオブジェクト同士を関わらせることで1つの処理を作り上げることがオブジェクト指向です！<br>
※この記事はオブジェクト指向の基本的用語は理解している上で記述しています。用語については[こちらのサイト](https://wa3.i-3-i.info/)がとても分かりやすくておすすめです！

#  単一責任の原則
オブジェクト指向の中核をなす概念の一つに、<font color="red">**単一責任の原則**</font>があります。<br>これは、名前の通り、**一つのオブジェクトには一つの責任がある**という考え方です。笑<br>
具体的に説明します。<br>それぞれの物に関する処理を、クラスという設計図に分けます。<br>今回のゲームでは、以下のようにクラス分けしました。
| クラス名 | 用途 | 
|:-----------|:------------|
| Mainクラス       | ゲーム全体の実行        | 
| Cardクラス     | カードに関する実行全て      | 
| Playerクラス       | Cardを継承してカードを引く        |
| Handクラス       | 勝敗の判定全般        |


もちろん、全ての処理をMainクラスに書くこともできますが（オブジェクト指向を使わない書き方）、もしカードの枚数が増えたら？もしプレイヤーの人数が増えたら？<br>そんな時にスムーズに変更できるのがクラス分けの利点です。

はい。**仕様変更があっても編集箇所は少なくて済む**ということが、オブジェクト指向の大きな利点であり、単一責任の原則なのです！

オブジェクト指向は、単一責任の原則をもとに、<font color="red">**三つの重要概念**</font>が存在しています。<br>今から一つずつ説明して、さらにオブジェクト指向を自分のものに説明していきます！

# 継承
お待たせしました。ここからはオブジェクト指向の三代重要概念のお話しです。<br>まず一つ目、**継承**です。<br>早速ですが先ほど記載したクラスの表をご覧ください。
Playerクラスの用途の部分に注目です。

| クラス名 | 用途 | 
|:-----------|:------------|
| Mainクラス       | ゲーム全体の実行        | 
| Cardクラス     | カードに関する実行全て      | 
| Playerクラス       | Cardを<font color="red">**継承**</font>してカードを引く        |
| Handクラス       | 勝敗の判定全般        |

この継承とは、**クラスが他のクラスの持つメソッドを引き継ぐこと**です。
厳密に言えば、親クラスで定義した関数を、子クラスでも同じように使用することができる、と言うことです。

例えばCardクラスにある、シャッフルしたカードを得るgetCard()メソッドを記載していて、プレイヤーそれぞれにカードを配りたい時、同じようにPlayerクラスでもgetCard()メソッドを使用したいと考えます。
その時に使えるのが継承です。

書き方は以下の通りです。
```PHP

class Card{
    private array $playerCards;

    public function getCard(){
        return $this->playerCards;
    }
}


class Player extends Card{
}

  $saito = new Playe();
  $saito->getCard();
```


# ポリモーフィズム
次に、二つ目のポリモーフィズムについてです。<br>んー、難しい言葉。と思いましたがそれは第一印象だけ。日本語に訳すと**多様性**という言葉になります。<br>多様性。私が前のクールでめちゃ好きだったテレビドラマ「不適切にもほどがある！」のセリフでもよく出てきました。笑

話が逸れましたが、ポリモーフィズムとは、**プログラムを記述する際に、同じ名前のメソッドや関数であっても、中身の違いによってそれぞれのオブジェクトに合わせた異なる動作をするというもの**です。<br>この考え方により、プログラムで同じ命令を実行しても、**それぞれが独立した固有の処理**を行うことが可能になりました。多様性感じる…！笑<br>
例を挙げて説明しますね。私は現在、スクールでチーム開発をしています。チームメンバーは４人いますが、人間というものはコピーなんて存在しないので、みんなバラバラな挨拶をします。<br>そう、この例で例えるとポリモーフィズムとは、個々のメンバーが独自の挨拶をすると言うことです。<br>さらに、今後新しいメンバーが加わっても、挨拶をするという共通の処理はすでに書かれているので、新しいメンバーを加えるだけで済みます。つまり、学習カリキュラムがもう決まっているということです。

コードは以下の通りです。

```PHP

class TeamMember {
    protected $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function geetings() {
    }
}


class Member1 extends TeamMember {
    public function geetings() {
        echo $this->name . ": お疲れ様でーす。\n";
    }
}

class Member2 extends TeamMember {
    public function geetings() {
        echo $this->name . ": おはようございます。\n";
    }
}

class Member3 extends TeamMember {
    public function geetings() {
        echo $this->name . ": ごめんなさい今日も寝坊しました。\n";
    }
}

$tanaka = new Member3("Tanaka");
$tanaka->geetings();


```

こちらのコードの出力結果は、
```
Tanaka: ごめんなさい今日も寝坊しました。
```
です。（実際にそんなメンバーはいません。笑）

# カプセル化
最後に三つ目、**カプセル化**です。<br>
結構プログラミング用語って、言葉のそのままなことが多いな〜と、学んで感じました。今回もそんな感じです。
メソッドやプロパティなどは定義するときにアクセス権をつけます。
例えば今回のカードクラスを例に挙げて見ます。
```PHP
class Card{

private array $cards;
//プロパティ

public function shuffleCard(){
//メソッド
    shuffle($this->cards);
    $this->player1Cards = array_slice($this->cards, 0, 26);
    $this->player2Cards = array_slice($this->cards, 25);
}
}
```
それぞれメソッドとプロパティの頭に**private**と**public**という文字があります。
これが**アクセス権**であり、prvateがカプセル化したプロパティと言うことでございます。


| アクセス修飾子 | アクセスできる範囲 | 
|:-----------|:------------|
| public       | どこからでもアクセス可能        | 
| protected     | そのクラス自身、継承したクラス、親クラスからのみアクセス可能      | 
| private       | そのクラスからのみアクセス可能        |


# まとめ

いかがでしたでしょうか？<br>自分が書いたコードも全て共有したいところですが、現時点では、とりあえず希望通りに動作する程度の、まだ整理されていないコードですので、、、<br>オブジェクト指向の理解が深まったら、改めてシェアしたいと考えています！笑

最後まで読んでくださり、ありがとうございました！