PHP Interfaceについて

# Interface(インターフェース)について

- __インターフェース__: 　特定のメソッドがクラスによって実装されることを保証するための契約である。
インターフェースは `interface` キーワードを使用して定義される。
その中にはメソッドのシグネチャ (名前、引数の型と数、戻り値の型) のみが含まれる。
インターフェース自体はインスタンス化することはできない。抽象化クラスと似ているが普通のメソッド定義いわゆる普通のpublicメソッドで中身を記述することは不可。

- __具象クラス__: 　一つまたは複数のインターフェースを実装することが可能である。
これは `implements`キーワードを使用して行う。
具象クラスは、それが実装する全てのインターフェースに定義されている全てのメソッドを具体的に実装しなければならない。

- __インターフェースの実装__:  クラスがインターフェースを実装すると、そのクラスはインターフェースに定義されている全てのメソッドを具体的に実装しなければならない。
もしクラスがインターフェースの一部のメソッドしか実装されていない場合、PHP はエラーをスローする。

__●__ インターフェースの実装例

```php:sample.php
<?php
ini_set("display_errors", 1);
error_reporting(E_ALL);

// インターフェース
interface ProductInterface
{
    // メソッド名のみ定義する。中身は書けない
    public function getProduct(); // メソッド名しか定義できない
}

// インターフェース
interface NewsInterface
{
    // メソッド名のみ定義する。中身は書けない
    public function getNews(); // メソッド名しか定義できない
}

// 具象クラス
class BaseProduct
{
    public function echoProduct()
    {
        echo '親クラスです';
    }

    public function getProduct()
    {
        echo '親の関数です';
    }
}

// 具象クラス
class Product implements ProductInterface, NewsInterface  // インターフェースの場合は複数使用することが可能
{
    private $product = [];

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

    // ProductInterfaceで定義した getProduct()を必ず使用
    public function getProduct()
    {
        echo $this->product;
    }

    public function addProduct($item)
    {
        $this->product .= $item;
    }

    // NewsInterfaceで定義した getNews()を必ず使用
    public function getNews()
    {
        echo 'ニュースです';
    }

    public static function getStaticProduct($str)
    {
        echo $str;
    }
}

$instance = new Product('テスト');

var_dump($instance);

echo '<br>';

$instance->getProduct();
echo '<br>';

// $instance->echoProduct();
// echo '<br>';

$instance->addProduct('追加分');
echo '<br>';

$instance->getNews();
echo '<br>';

$instance->getProduct();
echo '<br>';

Product::getStaticProduct('静的');
echo '<br>';
```

# 親クラスも併せて継承する

```php:sample.php
<?php
ini_set("display_errors", 1);
error_reporting(E_ALL);

// インターフェース
interface ProductInterface
{
    // メソッド名のみ定義する。中身は書けない
    public function getProduct(); // メソッド名しか定義できない
}

// インターフェース
interface NewsInterface
{
    // メソッド名のみ定義する。中身は書けない
    public function getNews(); // メソッド名しか定義できない
}

// 具象クラス、親クラス
class BaseProduct
{
    public function echoProduct()
    {
        echo '親クラスです';
    }

    public function getProduct()
    {
        echo '親の関数です';
    }
}

// 具象クラス
class Product extends BaseProduct implements ProductInterface, NewsInterface // 親クラスも併せて継承
{
    private $product = [];

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

    // ProductInterfaceで定義した getProduct()を必ず使用
    public function getProduct()
    {
        echo $this->product;
    }

    public function addProduct($item)
    {
        $this->product .= $item;
    }

    // NewsInterfaceで定義した getNews()を必ず使用
    public function getNews()
    {
        echo 'ニュースです';
    }

    public static function getStaticProduct($str)
    {
        echo $str;
    }
}

$instance = new Product('テスト');

var_dump($instance);

echo '<br>';

$instance->getProduct();
echo '<br>';

$instance->echoProduct();
echo '<br>';

$instance->addProduct('追加分');
echo '<br>';

$instance->getNews();
echo '<br>';

$instance->getProduct();
echo '<br>';

Product::getStaticProduct('静的');
echo '<br>';
```