Абстрактные классы
PHP 5 поддерживает определение абстрактных классов и методов. Объекты классов, определенные, как абстрактные, не могут быть созданы, и любой класс, который содержит по крайней мере один абстрактный метод, должен быть определен, как абстрактный. Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл и не могут включать реализацию.
При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в дочернем классе; кроме того, область видимости этих методов должна совпадать (или быть менее строгой). Например, если абстрактный метод объявлен как protected, то реализация этого метода должна быть protected или public, но не private. Более того, объявления методов должны совпадать, то есть контроль типов (type hint) и количество обязательных аргументов должно быть одинаковым. К примеру, если в дочернем классе указан необязательный параметр, которого нет в объявлении абстрактного класса, то в данном случае конфликта объявлений методов не будет. Это правило также применяется к конструкторам начиная с версии PHP 5.4, ранее объявления конструкторов могли отличаться.
Пример #1 Пример абстрактного класса
<?php
abstract class AbstractClass
{
/* Данный метод должен быть определён в дочернем классе */
abstract protected function getValue();
abstract protected function prefixValue($prefix);
/* Общий метод */
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
Старый код, который не имеет определенных пользователем классов или функций с именем 'abstract', должен работать без изменений.