PHPの継承についてまとめてみた（abstract,interface,trait）

#簡単なまとめ
![スクリーンショット 2021-07-04 16.15.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916260/0aa2eb55-a431-1084-8f75-e76c85a19128.png)

#具象クラス　class
1. `class 子クラス名 extends 親クラス名 `　という書き方で継承できる。
2. 親クラスで指定したメソッドを子クラスですべてオーバーライド（上書き）する必要はない。
2. １つの子クラスにつき、１つの親クラスのみしか継承できない（単一継承）

サンプルコード

```php
<?php

// 親クラスの定義
class ParentClass {
    protected $parent = "親クラスで定義";

    public function parent_method1(){
        echo $this->parent;
    }

    public function parent_method2(){
        echo "親クラスメソッド２";
    }
}

// 子クラスの定義
class ChildrenClass extends ParentClass {
    protected $children = "子クラスで定義";
    // 親クラスのメソッドをオーバーライド
    public function parent_method1(){
        echo $this->children;
    }
}

// 子クラスのインスタンス化
$instance = new ChildrenClass;
$instance->parent_method1(); //実装結果 子クラスで定義
```

#抽象クラス　abstract
1. `abstract class 抽象クラス名`で、抽象クラスを定義する。
1. １つの子クラスにつき、１つの親クラスのみしか継承できない（単一継承）
2. 抽象クラスは継承することを前提として使用するため、抽象クラスのインスタンス化はできない。
3. `class 継承先のクラス名 extends 抽象クラス名 `という書き方で継承できる。
3. 抽象メソッドにはメソッド名、返り値の型、引数のみしか指定できない。(引数と返り値の型は任意)
3. 抽象メソッドは`abstract アクセス修飾子 function 抽象メソッド名(引数の型 引数): 返り値の型;`という構文からなる。
4. 抽象クラスのメソッドを継承先のクラスですべて使用する必要はないが、***抽象メソッドで定義したものについては必ず継承先のクラスでオーバーライドする必要がある。***
4. 抽象メソッドとは対照的に抽象プロパティは存在しない

```php
<?php

// 抽象クラスの定義
abstract class AbstractClass {
    protected $abstract = "抽象クラスで定義";

    // 普通のメソッド（継承クラスでオーバーライドしてもしなくてもOK）
    public function common_method(){
        echo $this->abstract;
    }

    // 抽象メソッド（継承クラスでオーバーライドしない場合エラーとなる）
    abstract public function abstract_method(int $id): string;
}

// 子クラス(継承クラス)の定義
class ChildrenClass extends AbstractClass {
    protected $children = "継承クラスで定義した文字列";
    // 親クラスのメソッドをオーバーライド（引数や型を指定した場合は、継承先でも記述しなければエラーとなる）
    public function abstract_method(int $id): string{
        return $this->children;
    }
}

// 子クラスのインスタンス化
$instance = new ChildrenClass;
$id = 1;
echo $instance->abstract_method($id);  //実行結果　　継承クラスで定義した文字列

```

# インターフェース　interface
1. インターフェースはメソッド名、引数、返り値の型のみしか宣言できない。(プロパティの宣言は不可）
1. `interface インターフェース名`で宣言する
1. アクセス修飾子は`public`のみしか使用できない
1. 実装（継承）には`class 継承クラス名 implements インターフェース名`という書き方をする。
1. インターフェースは複数のインターフェースを実装することができる。（複数継承）
1. インターフェースはクラスではないのでインスタンス化はできない。
1. ***インターフェースで宣言したメソッドは全てオーバーライドする必要がある。***


```php
<?php

// インターフェースの宣言
interface SampleInterface1 {
    public function interface_method1();
}
interface SampleInterface2 {
    public function interface_method2(int $id): string;
}

// インターフェースを実装(継承)
class ChildrenClass implements SampleInterface1, SampleInterface2 {
    protected $children1 = "継承クラスで定義した文字列１";
    protected $children2 = "継承クラスで定義した文字列２";

    // インターフェースで宣言したメソッドをすべてオーバーライド
    public function interface_method1() {
        return $this->children1;
    }
    public function interface_method2(int $id): string {
        return $this->children2;
    }
}

// 子クラスのインスタンス化
$instance = new ChildrenClass;
$id = 1;
echo $instance->interface_method1(); //実装結果　継承クラスで定義した文字列１
echo "<br>";
echo $instance->interface_method2($id); //実装結果　継承クラスで定義した文字列２

```

# トレイト　trait
1. トレイトはコードの再利用性を高めるために利用する
1. トレイトは`trait トレイト名`で定義する
1. トレイトを使う際には、使いたいクラスの中で`use トレイト名`でトレイトを呼び出すことができる
1. クラス内で複数のトレイトを使うことができる。
1. トレイトはクラスではないため、インスタンス化はできない。

```php
<?php

// トレイトの宣言
trait SampleTrait1 {
    public $trait_value = "トレイト１";
    public function trait_method1(){
        return $this->trait_value;
    }
}
trait SampleTrait2 {
    public function trait_method2(){
        echo "トレイト２";
    }
}

// トレイトを使用するクラスの定義
class ChildrenClass {

    // トレイトをuseする
    use SampleTrait1;
    use SampleTrait2;
}

// 子クラスのインスタンス化
$instance = new ChildrenClass;
echo $instance->trait_method1(); //実装結果　トレイト１
echo "<br>";
echo $instance->trait_method2(); //実装結果　トレイト２

```

#補足　〜宣言と定義〜
記事をいくつか読んでいくうちに、「定義」や「宣言」といった言葉が見られたのですが、この２つの言葉の使われ方で違いってあるのかな？と思って調べて見ました。
・・・PHPの記事はほとんど見つけられませんでした。
C/C++などでは定義と宣言について違いがあるようですが、PHPではあまり重視されていないのでしょうか？
以下はJavaでの定義と宣言の違いについて書かれている記事から抜粋しました。

>宣言：変数の型＋変数名
定義：変数に具体的な数値などが入ったもの

#参考
以下のサイトを参考にして記事を書かせて頂きました。

https://qiita.com/yukiyohure0923/items/0e49a313b2b8c98d3a29
https://havelog.aho.mu/develop/php/e166-php-interface-abstract.html
https://webukatu.com/wordpress/blog/21566/#i-4

![スクリーンショット 2021-07-04 16.14.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916260/38f0e3a2-de1f-e555-b36b-5907800a8a41.png)