phpの基本を学んでみよう3（オブジェクト指向の基本-継承）

#近況報告

エンジニア転職成功しました。YouTubeでエンジニア転職したい方向けに情報発信しています。

https://www.youtube.com/channel/UCcXQG8lu_EdyP2Cbhtz1bcA



phpの基本を学んでみようシリーズ3
今回はオブジェクト指向の基本-継承までです。

#著者略歴
名前：[YUUKI](https://twitter.com/bitcoinjpnnet)
ポートフォリオサイト：[Pooks](https://pooks.herokuapp.com)
現在：Webエンジニア見習い

##クラスプロパティ

- メニュー数=インスタンス数
- インスタンスを「クラス全体で管理」する際に用いる
- クラスが持つデータ＝クラスプロパティ
- 「static」で定義
- 「クラス名::クラスプロパティ名」でアクセス

書き方

```php
<?php
  class Menu{
    // クラスプロパティの定義
    public static $count = 4;
  }

  // クラスプロパティにアクセス
  echo Menu::$count;
?>
```

##コンストラクタの活用

- 生成されたインスタンス数が変化した時に自動的に$countの値が変わるようにする

```php
<?php
  class Menu{
    public static $count = 0;
    public function __construct(){
      self::$count++;
    }
  }

// インスタンスが生成される度に$countの値を増やす
$curry = new Menu('CURRY');
$pasta = new Menu('PASTA');
?>
```

##self

- クラス内でクラスプロパティにアクセスする際に使用
- クラス自身のことを指す
- 「self::$クラスプロパティ名」のように使う

```php
<?php
  class Menu{
    public static $count = 0;
    public function __construct();
      // Menuクラスにアクセス
      self::$count++;
    }
  }

$menu1 = new Menu('CURRY');
$menu2 = new Menu('PASTA');

echo Menu::$count;
?>
```

##クラスメソッド

- static を用いて定義し、「クラス名::クラスメソッド名」のように呼び出す
- 個々のインスタンスのデータに関係ない処理を行いたい時に用いる

使い方

```php
<?php
  class Menu{
    private static $count = 0;
    // クラスメソッドの定義
    public static function getCount(){
      return self::$count;
    }
  }

  $menu1 = new Menu('CURRY');
  $menu2 = new Menu('PASTA');
  
  // クラスメソッドの呼び出し
  echo Menu::getCount();
?>
```

##継承

- すでに定義されているクラスのプロパティやメソッドを別のクラスに引き継ぐこと
- 親クラス
    - 子クラス
    - 子クラスは、親クラスのプロパティやメソッドを全て引き継いだ上で「独自の機能」を追加できる。

書き方

```php
<?php
  // 親クラス
  class 親クラス名{
  }

  // 子クラス
  class 子クラス extends 親クラス名{
  }
?>
```

###独自プロパティ、独自メソッド

- 子クラスに独自のプロパティを追加すること
- 子クラスで定義したプロパティやメソッドは親クラスで呼び出せない

###メソッドの呼び出し

- 子クラスのメソッド呼び出し時には、メソッドが検索される
- 子クラスにメソッドが定義されている場合には子クラスが、そのメソッドが定義されていない場合には親クラスのメソッドが定義される。

###instanceof

- あるインスタンスが特定のクラスのインスタンスであるか「判別」することができる
    - インスタンスが指定したクラスのインスタンス
        - true
    - そうでない
        - false


書き方

```php
<?php
  $coffee = new Drink('COFFEE');
  $curry = new Food('CURRY');

  // $coffeeDrinkクラスのインスタンスであるかどうか
  if($coffee instanceof Drink){
    echo $coffee->getName();  // trueなのでgetNameが呼び出される
  }

  // $curryはDrinkクラスのインスタンスであるかどうか
  if($curry instanceof Drink){
    echo $curry->getName(); // falseなのでgetNameは呼び出されない
  }
?>
```

##オーバーライド

- メソッドの上書きのこと
- 親クラスで定義されている同じ名前のメソッドを子クラスで再定義し、上書きする

```php
<?php
  class Drink extends Menu{
    private $type;
    // 親クラスで定義されているconstructをオーバーライドする
    public function __construct($name,$type){
      $this->name = $name;
      $this->type = $type;
    }
  }

  // 子クラスからの呼び出し（オーバーライド）
  $coffee = new Drink('COFFEE');
?>
```

###子クラスとアクセス権

- privateプロパティは「子クラス」からもアクセスできない

例

```php
// 親クラス
class Menu{
  private $name;
}

// 子クラス
class Drink extends Menu{
   public function __construct($name){
   // privateなのでアクセスできない
   $this->name = $name;
   }
}
```

####protected

- 子クラスから親クラスで定義したプロパティにアクセスする為に使う
- アクセス権がprotectedの場合
    - クラス内
    - クラスを継承している子クラス

からのみアクセス可能

####アクセス権まとめ

| アクセス権     | public | protected | private |
|:------------|:-----------:|:------------:|:------------:|
| クラス内      | ◯ | ◯ | ◯ |
| 子クラス内     | ◯ | ◯ | × |
| クラス、子クラス外 | ◯ | × | × |


###parent

- オーバーライドの際に親クラスで定義したメソッドを呼び出したいときに用いる
- 「parent::メソッド名」のようにする
- 「parent::メソッド名」を記述した場所で、親クラスのメソッドが実行される

書き方

```php
<?php
// 親クラス
  class Menu{
    private $name;

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

// 子クラス
  class Drink extends Menu{
  public function __construct($name, $price, $image, $type){
    // 親クラスの「__constructメソッド」を呼び出す
    parent::__construct($name, $price, $image);
    $this->type = $type;
  }
?>
```