Абстрактные классы, геттеры и сеттеры
Шаблон-заготовка, который нельзя создать напрямую, и умные свойства с логикой доступа.
Абстрактный класс — заготовка, которую нельзя инстанцировать; она задаёт общую структуру для наследников.
Абстрактные классы
Иногда базовый класс не должен существовать сам по себе — он лишь общий каркас. Например, «фигура вообще» — это абстракция; реальны только конкретные фигуры. Ключевое слово abstract запрещает создавать объект такого класса:
abstract class Shape {
abstract area(): number; // метод без тела — наследник обязан реализовать
describe(): string { // обычный метод — общий для всех
return "Площадь: " + this.area();
}
}
const s = new Shape();
// Ошибка: Cannot create an instance of an abstract class.
Абстрактный метод area() объявлен без тела. Это контракт: каждый наследник обязан его реализовать, иначе ошибка компиляции.
Наследник реализует абстрактное
class Square extends Shape {
constructor(private side: number) { super(); }
area(): number { return this.side ** 2; }
}
const sq = new Square(5);
console.log(sq.describe()); // "Площадь: 25"
Square реализовал area() и сразу получил готовый describe() от родителя. Это удобно: общую логику пишут один раз в абстрактном классе, а различия — в наследниках.
Абстрактный класс или интерфейс?
| Интерфейс | Абстрактный класс |
| только описание, без кода | может содержать готовые методы и поля |
| класс реализует несколько | наследуется только один |
Берут абстрактный класс, когда у наследников есть общий код; интерфейс — когда нужен только контракт без реализации.
Геттеры и сеттеры
Геттер и сеттер выглядят как обычное свойство, но за обращением скрывается метод. Это позволяет добавить логику при чтении и записи, не меняя синтаксис вызова:
class Temperature {
private _celsius: number = 0;
get celsius(): number {
return this._celsius;
}
set celsius(value: number) {
if (value < -273.15) {
throw new Error("Ниже абсолютного нуля нельзя");
}
this._celsius = value;
}
get fahrenheit(): number {
return this._celsius * 9 / 5 + 32; // вычисляется на лету
}
}
const t = new Temperature();
t.celsius = 25; // вызовется сеттер с проверкой
console.log(t.celsius); // 25 — вызовется геттер
console.log(t.fahrenheit); // 77 — вычисляемое свойство
Снаружи это выглядит как простое присваивание t.celsius = 25, но внутри срабатывает проверка. А fahrenheit — вычисляемое свойство только для чтения: сеттера у него нет, поэтому записать в него нельзя.
Зачем это: валидация и инкапсуляция
Геттеры и сеттеры дают контроль над доступом к полю, сохраняя удобный синтаксис свойства. Можно проверять значения при записи, считать производные данные при чтении, логировать обращения — и при этом код снаружи не знает, что за свойством стоит логика.
Итог
abstract-класс нельзя создать напрямую; его абстрактные методы обязаны реализовать наследники.- Абстрактный класс хранит общий код для наследников; интерфейс — только контракт.
- Геттеры/сеттеры добавляют логику (валидацию, вычисление) при чтении и записи, сохраняя синтаксис обычного свойства.