Пример ответа
1) Короткий ответ
Интерфейс объявляет контракт (что класс должен делать), а абстрактный класс может частично реализовывать функциональность и часто выражает отношение «is-a».
4) Сравнение
Критерий | Интерфейс (с PHP 8.0+) | Абстрактный класс |
---|---|---|
Реализация | Только сигнатуры методов (до PHP 8.0). Теперь можно добавлять | Может содержать реализованные и абстрактные методы, свойства. |
Наследование | Класс может реализовать несколько интерфейсов. | Класс может наследовать только от одного абстрактного класса. |
Состояние | Не может содержать свойства (кроме констант). | Может содержать свойства-члены с модификаторами доступа. |
Тип отношения | «Реализует способность» (например, | «Является разновидностью» (например, |
Рекомендация: Используйте интерфейсы для определения контрактов, которые могут быть реализованы разными несвязанными классами. Абстрактные классы подходят для шаблонного метода (template method), когда у классов есть общая базовая логика.
5) Пример кода
php
Copy
Download
// Интерфейс - контракт для возможности логирования
interface Logger {
public function log(string $message): void;
}
// Абстрактный класс - базовая реализация для контроллеров
abstract class BaseController {
protected string $name;
public function __construct(string $name) {
$this->name = $name;
}
abstract public function handle(): Response; // Должен быть реализован
protected function logAction(): void {
// Общая логика для всех контроллеров
echo "Action in {$this->name}";
}
}
6) Follow-up вопросы
Когда выбрать трейт вместо интерфейса? → Повторное использование кода.
Можно ли объявить приватный метод в интерфейсе? → Нет, только public.
7) Практический совет
Создайте интерфейс
Cacheable
с методамиget()
/set()
и реализуйте его в 2 классах:RedisCache
иFileCache
.Сделайте абстрактный класс
AbstractRepository
с общим методомfind()
и унаследуйте от негоUserRepository
, переопределив абстрактныйgetTableName()
.