はじめに
PHPのオブジェクト指向の学習を進めていく中で、抽象クラス
とインターフェース
という似た性質を持つ仕組みがあることを知った。
初学者にはその違いがわかりにくかったため、それぞれにどのような特徴があるのかをまとめることにした。
抽象クラスとは
以下に、抽象クラスの特徴をまとめる。
- 抽象クラスは他のクラス(サブクラス)に extends されることを前提としている。サブクラスが抽象クラスを継承することで、共通の機能や特性を利用できる。
- 抽象メソッドと
通常のメソッド、プロパティ
を実装することができる。 - サブクラスは`抽象メソッドを必ず実装する必要があるが、通常のメソッドはオーバーライドする必要がない。
- サブクラスは
1つの抽象クラスしか継承できない
が、通常のクラスと同じように、プロパティや通常のメソッドを継承できる。 - 抽象クラス自体は
直接インスタンス化できない。
サブクラスを通じてインスタンス化する必要がある。 -
コンストラクタ(__constructメソッド)を実装できる。
サブクラスが抽象クラスを継承する際に、親クラスのコンストラクタも呼び出される。
以下に、上記特徴を持つプログラムの例を挙げる。
<?php
// 抽象クラスの定義
// インスタンス化できない
abstract class Animal
{
// プロパティの宣言
protected $name;
// コンストラクタの実装
public function __construct($name)
{
$this->name = $name;
}
// 通常のメソッドの実装
public function sleep()
{
return $this->name.'は寝ています。';
}
// 抽象メソッドの実装
abstract public function makeSound();
// サブクラスが抽象クラスを継承する
// 抽象クラスのプロパティや通常のメソッドを継承できる
// 抽象クラスのコンストラクタを継承できる
class Dog extends Animal
{
// 抽象メソッドは必ず実装
// 通常のメソッドはオーバーライドする必要がない
public function makeSound()
{
return $this-name.'がワン!と鳴きました。';
}
}
}
上記例では、 Animal という抽象クラスがあり、 Dog というサブクラスがそれを継承している。
Animal クラスは、通常のメソッド sleep() と抽象メソッド makeSound() を実装し、プロパティ $name を宣言している。コンストラクタも実装している。
Dog クラスで抽象メソッド makeSound() の実装を行っている。
インターフェース
以下に、インターフェースの特徴をまとめる。
- インターフェースは他のクラスに implements されることを前提としている。インターフェースは、その中で定義されたメソッドの実装をクラスに強制する。
- 全てのメソッドが抽象メソッド扱いとなり、
通常のメソッドは実装できない。
※PHP 8.0以降ではプロパティの宣言が可能。 - インターフェースを実装したクラスは、インターフェースの全てのメソッドを実装する必要がある。
- クラスは
複数のインターフェースを同時に実装できる。
- インターフェースは
コンストラクタを持つことができない。
以下に、上記特徴を持つプログラムの例を挙げる。
<?php
// 1つ目のインターフェースの実装
interface Animal
{
// 抽象メソッドの実装
public function makeSound();
// 通常のメソッド、コンストラクタの実装ができない
}
// 2つ目のインターフェースの実装
interface Action
{
// 抽象メソッドの実装
public function doAction();
}
// クラスが複数のインターフェースを同時に実装する
class Dog implements Animal, Action
{
// 抽象メソッドは必ず実装
public function makeSound()
{
return 'ワン!と鳴きました。';
}
// 抽象メソッドは必ず実装
public function doAction()
{
return 'おすわりしました。';
}
}
上記例では、 Animal と Action という2つのインターフェースがあり、 Dog というクラスがそれを実装している。
Animal インターフェースは、抽象メソッド makeSound() を実装し、Action インターフェースは、抽象メソッド doAction() を実装している。
Dog クラスで抽象メソッド makeSound() と抽象メソッド doAction() の実装を行っている。
まとめ
PHPのオブジェクト指向において、抽象クラスとインターフェースは似た性質を持ちつつも異なる特徴があることがわかった。しかし、特徴を把握したは良いものの、どのような場面でどちらの仕組みを使えば良いかが全く理解できていない。
今後プログラムを作成する際は、今回整理した知識をもとに、抽象クラスとインターフェースを使い分けることを意識する。その後、使い分け方についてある程度整理ができた段階で追加の記事を作成しようと思う。