PHPでインターフェイスと抽象クラスを使う


##はじめに
インターフェイスと、抽象クラスの差がイマイチわからないです。
間違った解釈の場合コメントください。


##インターフェイス

クラスが実装する必要があるメソッドの種類を、メソッドの実体を定義することなく作成することができます。


```
<?php

interface IShowName {
  public function showName();
}

interface IShowAge {
  public function showAge();
}

class User implements IShowName, IShowAge{

  public function showName(){
    echo 'SATO';
  }

  public function showAge(){
    echo '55';
  }
}

?>
```

###インターフェイスの定義方法
インターフェイスを定義するには、``interface``を使用します。

* インターフェイスで定義できるのは、実装を持たない抽象メソッドのみ
* アクセス修飾子は``public``のみ
* 定数を持つことができますが、実装先のクラスでオーバーライドすることはできません。


```
interface インターフェイス名 {
	const 変数名 = 'ABC';
	public function メソッド名();
}
```

###インターフェイスの実装方法

インターフェイスは、``implements``キーワードを使用して実装します。
インターフェイスは``,``で区切れば複数指定することができます。

```
class クラス名 implements インターフェイス名,インターフェイス名
```

###インターフェイスで宣言されたメソッドは必ず、実装しなくてはいけない

インターフェイス内で定義しているメソッドは、class内でオーバーライドしないとエラーになります。

```
<?php

interface IShowName {
  public function showName();
}

interface IShowAge {
  public function showAge();
}

class User implements IShowName, IShowAge{
}

?>

//エラーが発生
//Fatal error: Class User contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods 
```

インターフェイスで定義した定数を、実装先のクラスでオーバーライドした場合エラーとなります。

```
interface IShowName {
  const name = 'KATO';
}

class User implements IShowName{
  const name = 'SATO';

}

//Fatal error: Cannot inherit previously-inherited or override constant name from interface IShowName
```

##抽象クラス
抽象クラスとは、他のクラスで継承してもらうことを前提としたクラス。
抽象クラス自体をインスタンス化することはできません。

```
<?php

abstract class BaseUser{
  public $name;
  abstract public function showName();
}

class User extends BaseUser{
  public function showName(){
    echo 'SATO';
  }
}

?>
```

###抽象クラスの定義方法

抽象クラスは、``abstract``キーワードを使用します。

```
abstract 抽象クラス名{
}
```

###抽象メソッドの定義
抽象クラスは、抽象メソッドを定義できます。
定義するには、抽象クラス作成時と同じく``abstract``キーワードを使用します。

* アクセス修飾子には``public``、``protected``が使用できます。

```
abstract 抽象クラス名{
	abstract public function showName();
}
```

###抽象クラスの継承方法

抽象クラスは、通常のクラス同様``extends``キーワードを使用して継承します。
抽象クラス内で定義している、抽象メソッドは、必ず継承先でオーバーライドする必要があります。
オーバーライドしていない場合エラーとなります。

また、``extends``で継承する為複数の抽象クラスを継承することはできません。

```
<?php

abstract class BaseUser{
  public $name;
  abstract public function showName();
}

class User extends BaseUser{
}

?>

//エラーが発生
//Fatal error: Class User contains 1 abstract method and must therefore be declared abstract or implement the remaining methods

```

抽象クラスは、通常のクラス同様、プロパティやメソッドを実装できます。

```
<?php

abstract class BaseUser{
  //通常のクラス同様、プロパティやメソッドを定義
  public $age = 55;
  public function showAge($age){
    echo $age;
  }
  //抽象メソッド
  abstract public function showName();
}

class User extends BaseUser{

  function __construct(){
      $this->showName();
      $this->showAge($this->age);
  }

  public function showName(){
    echo 'SATO　';
  }
}

$user = new User();//SATO　55

?>
```

##インターフェイスと、抽象クラスの違い
* インターフェイスは、クラスに複数実装できるが、抽象クラスは１つしか継承できない。
* インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。

###インターフェイスと、抽象クラスの使い分け
####◎抽象クラス
#####抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合などに使用する。

アイドルに、「歌う、踊る、ファンと触れ合う」、という機能があるとして「ファンと触れ合う」はアイドルによって、ふれあい方が違うから、それぞれ実装したい場合などに使うみたい。

####◎インターフェイス
#####不特定のクラスで、共通のメソッドを定義したい場合。

インターフェイスは、クラスで使用できるメソッドを保証しているので、クラスの使用書的な意味合いがありるみたいです。

##終わり
ある程度の規模のアプリケーションや、複数人での開発をしないと抽象クラスも、インターフェイスも有り難みがわからないのかもしれません。