Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Middle ООП

Що означає final і чому класи радять робити final за замовчуванням?

  • final class - від класу не можна успадкуватися.
  • final public function - метод не можна перевизначити в нащадку.
  • final const (PHP 8.1) - константу не можна перевизначити.
final class InvoiceNumberGenerator
{
    public function next(): string { /* ... */ }
}

class Report extends InvoiceNumberGenerator {}  // Fatal error

Чому final за замовчуванням:

  • Успадкування - найсильніший зв'язок. Нащадок залежить від усіх деталей предка. Будь-яка зміна в класі може зламати чужого нащадка, про якого автор навіть не знає.
  • Свобода змінювати клас. Якщо клас final, його внутрішню будову (protected-методи, порядок викликів) можна змінювати вільно: зовні доступний лише публічний API.
  • Свідомі рішення. Прибрати final, коли з'явилася реальна потреба в успадкуванні, - одна правка. Повернути final, коли на клас уже успадковуються, - ламаюча зміна.
  • Підштовхує до композиції й інтерфейсів замість ієрархій.

Типове заперечення - «а як мокати в тестах?». Мокати слід інтерфейси, а не конкретні класи. Якщо клас треба підмінити, - він реалізує інтерфейс, і тест підставляє іншу реалізацію. Для зовнішніх final-класів бібліотек є обхідні шляхи (пакет dg/bypass-finals), але це сигнал щодо дизайну.

Де final не ставлять: базові класи, призначені для успадкування (Model, Controller, абстрактні класи), і класи, які фреймворк проксує чи розширює під час виконання (наприклад, моделі Doctrine з лінивими проксі).

Докладніше в документації: Ключове слово final

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання