← Назад к вопросам

Что такое Abstract Class в TypeScript?

2.0 Middle🔥 161 комментариев
#JavaScript Core#TypeScript

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Abstract Class в TypeScript?

Abstract Class (абстрактный класс) в TypeScript — это специальный класс, который не может быть инстанциирован напрямую (т. е. нельзя создать экземпляр через new), а предназначен для того, чтобы быть базовым классом, от которого наследуются другие классы. Он служит шаблоном для будущих классов, определяя общую структуру и поведение, которые должны быть реализованы в дочерних классах.

Ключевые характеристики abstract class

  • Нельзя инстанциировать напрямую: Попытка создать экземпляр абстрактного класса приведёт к ошибке компиляции.
  • Может содержать абстрактные методы: Это методы, объявленные с ключевым словом abstract, которые не имеют реализации в абстрактном классе. Их реализация обязательна в дочернем, не абстрактном классе.
  • Может содержать реализованные методы: Абстрактный класс может также иметь обычные методы с полной реализацией, которые наследуются дочерними классами.
  • Может содержать свойства (поля): Как абстрактные (только объявление), так и обычные с инициализацией.
  • Использует наследование: Дочерний класс наследует абстрактный класс с помощью ключевого слова extends.

Синтаксис и примеры

// Объявление абстрактного класса
abstract class Animal {
    // Обычное свойство
    protected name: string;

    constructor(name: string) {
        this.name = name;
    }

    // Абстрактный метод - БЕЗ реализации.
    // Обязателен для реализации в дочернем классе.
    abstract makeSound(): void;

    // Обычный, реализованный метод. Будет унаследован.
    move(distanceInMeters: number = 0): void {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

// Дочерний, конкретный класс
class Dog extends Animal {
    constructor(name: string) {
        // Вызов конструктора родительского класса
        super(name);
    }

    // ОБЯЗАТЕЛЬНАЯ реализация абстрактного метода
    makeSound(): void {
        console.log(`${this.name} barks: Woof! Woof!`);
    }

    // Можно добавить свои методы
    wagTail(): void {
        console.log(`${this.name} wags its tail.`);
    }
}

// Другой дочерний класс
class Snake extends Animal {
    constructor(name: string) {
        super(name);
    }

    // Своя реализация абстрактного метода
    makeSound(): void {
        console.log(`${this.name} hisses: Sssss...`);
    }

    // Можно переопределить и обычный метод
    move(distanceInMeters = 5): void {
        console.log('Slithering...');
        super.move(distanceInMeters); // Можно вызвать родительскую версию
    }
}

// Использование:
const myDog = new Dog('Rex');
myDog.makeSound(); // "Rex barks: Woof! Woof!"
myDog.move(10);    // "Rex moved 10m." (унаследованный метод)
myDog.wagTail();   // "Rex wags its tail."

const mySnake = new Snake('Kaa');
mySnake.makeSound(); // "Kaa hisses: Sssss..."
mySnake.move();      // "Slithering..." \n "Kaa moved 5m."

// ОШИБКА КОМПИЛЯЦИИ: Нельзя создать экземпляр абстрактного класса
// const animal = new Animal('SomeAnimal');

Абстрактные свойства

Начиная с TypeScript 4.2, можно также объявлять абстрактные свойства.

abstract class Department {
    // Абстрактное свойство
    abstract readonly departmentCode: string;
    protected employees: string[] = [];

    // Абстрактный геттер
    abstract get departmentName(): string;

    addEmployee(employee: string): void {
        this.employees.push(employee);
    }
}

class ITDepartment extends Department {
    // Обязаны инициализировать абстрактное свойство
    readonly departmentCode: string = "IT";

    // Обязаны реализовать абстрактный геттер
    get departmentName(): string {
        return 'Information Technology Department';
    }
}

Отличия от интерфейсов (Interface)

Хотя и abstract class, и interface задают контракты, между ними есть важные различия:

  • Реализация: Abstract class может содержать реализацию методов и инициализированные свойства, interface — только декларацию.
  • Наследование vs Реализация: Класс extends (наследует) абстрактный класс, но implements (реализует) интерфейс.
  • Конструктор: У abstract class может быть конструктор, у interface — нет.
  • Модификаторы доступа: В abstract class можно использовать protected, private, readonly. В interface все члены по умолчанию public.
  • Наследование классов: Abstract class может наследовать только один другой класс (абстрактный или обычный), но может реализовывать множество интерфейсов. Класс может реализовывать множество интерфейсов, но наследовать только один класс.

Когда использовать Abstract Class?

  1. Когда несколько родственных классов имеют общую, частичную реализацию. Можно вынести общую логику в абстрактный класс, избежав дублирования кода.
  2. Когда нужно обязать дочерние классы реализовать специфичное поведение, определив абстрактные методы.
  3. Когда логично использовать наследование и цепочку прототипов. Абстрактный класс — это всё же класс, он отражает отношение "является" (Dog is an Animal).
  4. Когда нужен контроль над модификаторами доступа (protected, private) для внутреннего состояния.

Заключение

Abstract Class — это мощный инструмент объектно-ориентированного программирования в TypeScript, который позволяет создавать сложные иерархии классов, обеспечивая принудительное соблюдение контрактов через абстрактные члены и одновременно предоставляя готовую, переиспользуемую функциональность. Он идеально подходит для моделирования сущностей, имеющих чёткую логическую связь "родитель-потомок" и общую базовую функциональность.