PHP には、抽象クラスと抽象メソッドの機能があります。 abstract として定義されたクラスのインスタンスを生成することはできません。 1つ以上の抽象メソッドを含む全てのクラスもまた抽象クラスとなります。 abstract として定義されたメソッドは、そのメソッドのシグネチャを宣言するのみで、 実装を定義することはできません。
抽象クラスから継承する際、親クラスの宣言で abstract としてマークされた 全てのメソッドは、子クラスで定義されなければなりません。加えて、 オブジェクトの継承 と シグネチャの互換性に関するルール に従わなければいけません。
例1 抽象クラスの例
<?php
abstract class AbstractClass
{
// 拡張クラスにこのメソッドの定義を強制する
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Common method
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
?>
上の例の出力は以下となります。
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
例2 抽象クラスの例
<?php
abstract class AbstractClass
{
// 抽象メソッドでは、必須の引数だけを定義しています
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// 子クラスでは、親のシグネチャにないオプション引数を定義することもあるでしょう
public function prefixName($name, $separator = ".") {
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
上の例の出力は以下となります。
Mr. Pacman Mrs. Pacwoman