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

Що таке абстрактні класи і чим вони відрізняються від інтерфейсів?

Абстрактний клас не можна створити напряму (new), лише успадкувати. Він може містити і реалізацію, і абстрактні члени, які зобов'язаний реалізувати нащадок.

abstract class Notifier {
  abstract send(to: string, message: string): Promise<void>;

  async notifyAll(recipients: string[], message: string) {
    for (const to of recipients) {
      await this.send(to, message);
    }
  }
}

class EmailNotifier extends Notifier {
  async send(to: string, message: string) {
    // реалізація відправки
  }
}

new Notifier();        // помилка: абстрактний клас
new EmailNotifier();   // ок

Нащадок, що не реалізував усі абстрактні члени, теж мусить бути abstract.

Чим відрізняється від інтерфейсу:

Абстрактний клас Інтерфейс
реалізація методів може мати ні
поля зі значеннями, конструктор так ні
модифікатори protected, private так ні
існує під час виконання так (це клас JavaScript) ні (зникає при компіляції)
кількість на клас лише один (extends) скільки завгодно (implements)
instanceof працює неможливо

Коли абстрактний клас:

  • є спільна реалізація, а нащадки відрізняються окремими кроками - шаблонний метод: загальний алгоритм у базовому класі, змінні кроки - абстрактні;
  • потрібен спільний стан чи конструктор;
  • потрібна перевірка instanceof.

Коли інтерфейс:

  • потрібен лише контракт - форма об'єкта чи класу;
  • клас має відповідати кільком контрактам;
  • об'єкти можуть бути не екземплярами класів (звичайні об'єкти, моки в тестах).

Абстрактні конструктори в типах - щоб прийняти «будь-який підклас», а не сам абстрактний клас:

function register(Ctor: abstract new () => Notifier) {}

Обережно з глибокими ієрархіями: абстрактний клас, від якого успадковують усе, з часом обростає методами «для деяких нащадків». Для повторного використання поведінки часто краща композиція - передати залежність через конструктор.

Докладніше в документації: Абстрактні класи

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