PHPにおいてポリモーフィズム実現のために使われる抽象クラスとインターフェースですが、勉強していてややこしいなと感じたのでアウトプットを兼ねて記事にまとめます。
抽象クラス
抽象クラスとは、処理が記述されていないメソッド(抽象メソッド)を持つクラスのことです。クラス名と抽象メソッドの前にabstractと宣言することで定義できます。
特徴
- 通常のクラスと同様に処理を記載したプロパティやメソッドを定義できる(アクセス修飾子も自由)
- 抽象プロパティは定義できない
- 抽象メソッドのアクセス修飾子はpublicかprotected
- クラス名と抽象メソッドの前にabstractを宣言
- 直接インスタンス化できない
- extendsを使って継承
- 抽象メソッドは必ずオーバーライドしなければならない
使い方
AbstractAnimal.php
abstract class AbstractAnimal
{
// 通常のクラスと同様に処理を記載したプロパティやメソッドを定義できる(アクセス修飾子も自由)
private $weight = 10; // 継承しなければならないためprivateは基本使われません
protected function eat($food)
{
return "{$food}を食べる";
}
// 抽象プロパティは定義できない
//abstract public $height = 30;
// 抽象メソッド(処理は書かない)
// アクセス修飾子はpublicかprotected
abstract public function run($distance);
}
Dog.php
// 抽象クラスは直接インスタンス化できない
// $animal = new AbstractAnimal();
// extendsを用いて継承すればインスタンス化できる
// その際、必ず抽象メソッドをオーバーライドして処理を書かなければならない
class Dog extends AbstractAnimal
{
public function run($distance)
{
return "{$distance}を走る";
}
}
$dog = new Dog();
インターフェース
インターフェースとは、処理が記述されていないメソッド(抽象メソッド)と定数のみで構成されたもののことを指します。クラス名の前にinterfaceと宣言することで定義できます。
特徴
- 抽象メソッドと定数のみしか定義できない
- アクセス修飾子はpublicのみ
- クラス名の前にinterfaceを宣言
- 直接インスタンス化できない
- implementsを使って「実装」
- 抽象メソッドは必ずオーバーライドしなければならない
- 複数のインターフェースを指定して実装できる
使い方
Cat.php
interface Cat
{
// 抽象メソッドと定数のみを定義
const CUTENESS = "overloaded";
// アクセス修飾子はpublicのみ
public function eat();
public function run($distance);
}
interface Munchkin
{
const SHORTLEGS = true;
}
Tama.php
// インターフェースも直接インスタンス化できない
//$cat = new Cat();
// 複数のインターフェースを指定して実装できる
class Tama implements Cat, Munchkin
{
// 抽象メソッドはオーバーライドして処理を書かなければならない
public function eat()
{
return "食べる";
}
public function run($distance)
{
"{$distance}を走る";
}
}
$tama = new Tama();