abstract (抽象クラス)とは
abstractで定義された抽象クラスには以下のような性質があります
- 対象の具象クラス(※通常のクラス)にプロパティもしくはメソッドを強制的に定義させる
- 抽象クラス単体ではインスタンス化することはできない
- abstractとして定義したメソッドは具体的な処理を書くことはできない
- 抽象クラス内で具象クラス同様、具体的なメソッドを定義し、継承させることもできる
PHP公式リファレンスのコード例を引用したので、以下を見て下さい。
抽象クラスの例
abstract class AbstractClass // 抽象クラス
{
// 拡張クラスに以下のメソッドの定義を強制する
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 通常のメソッド
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass extends AbstractClass // 具象クラス
{
protected function getValue() { // AbstractClassで定義したabstractメソッド
return "ConcreteClass";
}
public function prefixValue($prefix) { // AbstractClassで定義したabstractメソッド
return "{$prefix}ConcreteClass";
}
}
$class = new ConcreteClass;
$class->printOut(); // => 'ConcreteClass"'
echo $class->prefixValue('FOO_') ."\n"; // => 'FOO_ConcreteClass'
上記の例では、
具象クラスであるConcreteClassクラスに抽象クラスのAbstractClassクラスを継承しています。
ConcreteClassクラスでは、AbstractClassクラスで定義したメソッド3つの内、
抽象メソッドであるgetValueメソッドとprefixValueメソッドを明示的に定義しています。
また、printOutメソッドは通常の継承と同様、
具象クラス内で定義しなくても呼び出すことができています。
もし、この2つのメソッドをConcreteClassクラス内で定義しなかった場合、以下のようにエラーが発生します。
class ConcreteClass extends AbstractClass
{
}
// => Fatal error: Class ConcreteClass contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (AbstractClass::getValue, AbstractClass::prefixValue) in /tmp/preview on line 15
ただの継承であれば、明示的に定義しなくても呼び出すことができますが、
抽象クラスを継承した具象クラス内で、
abstractメソッドを定義しないとエラーが発生するため、
具象クラスに継承させることで強制的にプロパティやメソッドを明示的に定義させる必要があります。
abstractの意義・目的
なぜ、わざわざ抽象クラスを作って具象クラスに継承させることでプロパティとメソッドを強制させるかというと、チームでの開発において有用だからです。
抽象クラスを継承した具象クラス内では必ず、抽象プロパティ・メソッドを定義しないといけないルールがあります。
そのため、共通の機能を持つ派生クラスであるということを保証、機能の漏れが減ることに繋がります。
さらに継承したクラス群はいずれも近しい機能を持ったクラスであるということが分かりやすくなるという意義もあります。
プロジェクトが大きくなり、開発する人数が増えれば増えるほど、
ファイル名やクラス名などからどういう機能を持ったものか推測することの重要性が増します。
抽象クラスにはそれを補助する役割があるわけです。
参考