В чём суть абстрактного класса
Абстрактный класс — это класс, который нельзя инстанциировать напрямую; он служит шаблоном для других классов, определяя общий интерфейс и частичную реализацию. В PHP абстрактный класс объявляется с ключевым словом abstract и может содержать как обычные методы с реализацией, так и абстрактные методы без тела, которые обязаны реализовать наследники.
Как это работает
Абстрактный класс предназначен для моделирования общих характеристик группы связанных объектов. Он позволяет:
- Определить общие свойства и методы, которые будут унаследованы всеми подклассами, что уменьшает дублирование кода.
- Объявить абстрактные методы — сигнатуры без реализации, которые каждый наследник обязан реализовать по-своему. Это гарантирует, что все подклассы имеют единый интерфейс, но могут вести себя по-разному.
- Инкапсулировать общую логику, которую нельзя изменять в наследниках (если метод не объявлен как
final).
В отличие от интерфейсов, абстрактный класс может содержать поля и реализацию методов, что делает его более гибким для частичного переиспользования кода.
Пример
Рассмотрим пример на PHP: абстрактный класс ТранспортноеСредство определяет общее свойство скорость и метод установитьСкорость(), а также требует от наследников реализовать метод двигаться().
abstract class ТранспортноеСредство {
protected $скорость;
public function установитьСкорость($скорость) {
$this->скорость = $скорость;
}
// Абстрактный метод: наследник обязан реализовать
abstract public function двигаться();
}
class Автомобиль extends ТранспортноеСредство {
public function двигаться() {
echo "Движется на скорости: " . $this->скорость . " км/ч";
}
}
// $транспорт = new ТранспортноеСредство(); // Ошибка: нельзя создать экземпляр абстрактного класса
$автомобиль = new Автомобиль();
$автомобиль->установитьСкорость(60);
$автомобиль->двигаться(); // Выведет: Движется на скорости: 60 км/чЗдесь ТранспортноеСредство задаёт общий каркас: любое транспортное средство имеет скорость и умеет её устанавливать, но способ движения у каждого свой. Попытка создать объект абстрактного класса приведёт к фатальной ошибке.
Подводные камни
- Нельзя инстанциировать: попытка
new АбстрактныйКласс()вызовет ошибку. Это важно для проектирования: абстрактный класс существует только как основа для наследования. - Обязательная реализация абстрактных методов: если наследник не реализует все абстрактные методы, он сам должен быть объявлен абстрактным, иначе возникнет ошибка.
- Ограничение одиночного наследования: в PHP класс может наследовать только один абстрактный класс, в отличие от интерфейсов, которых можно реализовать несколько. Это ограничение нужно учитывать при проектировании иерархии.
- Абстрактные методы не могут быть
private: они должны бытьprotectedилиpublic, чтобы наследники могли их реализовать.
Когда использовать
Абстрактный класс уместен, когда несколько классов имеют общую логику и состояние, но отличаются в некоторых ключевых аспектах. Например, базовый класс для различных видов животных, где общий метод есть() реализован, а издаватьЗвук() — абстрактный. Если же требуется только контракт без реализации, лучше выбрать интерфейс.
Коротко
- Абстрактный класс — это класс, который нельзя создать через
new; он служит шаблоном для наследников. - Он может содержать реализацию общих методов и абстрактные методы, которые наследники обязаны реализовать.
- Используется для уменьшения дублирования кода и гарантии единого интерфейса в группе связанных классов.
- Помните об ограничении одиночного наследования и о том, что абстрактные методы не могут быть
private.
