Итоги
В этом уроке вы узнали, что:
- Класс — это шаблон для объектов:
class Monster { name: string = "Гоблин"; }.new Monster()создаёт экземпляр, который выводится какMonster { name: "Гоблин" }. Имя класса — это ещё и тип:function hit(monster: Monster). - У каждого поля должно быть значение: начальное или заданное в конструкторе; иначе вы получите TS2564.
- Конструктор запускается при
newи получает его аргументы:constructor(name: string) { this.name = name; }. Внутри негоthis— это новый объект. Короткая записьconstructor(public name: string)здесь не разрешена (TS1294). - Методы — это функции в классе:
describe(): string { return this.name; }, вызываются какkira.describe(). Внутри методаthis— это объект перед точкой. Безthis.TypeScript сообщает TS2663. - Поле
privateможно использовать только внутри класса (в других местах будет TS2341); путь к нему лежит через методы. Безprivateчлен классаpublic. Собственные приватные поля JavaScript начинаются с#. - Поле
readonlyполучает значение только как начальное или в конструкторе (в других местах будет TS2540). class Wizard implements Characterзаставляет TypeScript проверить, что в классе есть всё, чего требует интерфейс (TS2420). TypeScript сравнивает формы, поэтому интерфейсу подходит любой объект нужной формы.class Boss extends Monsterнаследует поля и методы классаMonster. Его конструктор должен первым делом вызватьsuper(…)(TS2377).Bossподходит везде, где ожидаетсяMonster.- Производный класс может переопределить метод:
override describe(): string.overrideзаставляет TypeScript проверить, что у родителя есть такой метод (TS4117), аsuper.describe()вызывает версию родителя.
Дальше — последний небольшой проект: банк для авантюристов, построенный на классах и обобщениях. А потом, в уроке «Вспомогательные типы», вы будете строить новые типы из тех, что у вас есть: героя, у которого все свойства необязательны, героя без id и другие.
Но сначала соберите этот урок воедино. В сумке у Киры лежат разные вещи, которыми можно пользоваться. Интерфейс для них — в редакторе.
Задание
- 1
Напишите класс
Potion, который реализуетUsable. У него есть полеnameтолько для чтения и приватное полеdoses(число), оба задаёт конструктор. Его методuse()возвращает`${name}: пусто`, когда доз не осталось. Иначе он забирает одну дозу и возвращает`${name}: остаток ${doses}`, напримерЗелье лечения: остаток 1. - 2
Создайте
const potion = new Potion("Зелье лечения", 2);и используйте зелье три раза, каждый раз выводя то, что вернётuse():Зелье лечения: остаток 1 Зелье лечения: остаток 0 Зелье лечения: пусто - 3
Напишите второй класс,
Scroll, который тоже реализуетUsable. У него естьnameиspellтолько для чтения, оба задаёт конструктор, а егоuse()возвращает`${name}: вы читаете заклинание ${spell}`. Затем положите в сумку новое зелье и свиток,const bag: Usable[] = [new Potion("Зелье маны", 1), new Scroll("Свиток света", "Свет")];, и используйте всё, что лежит в сумке, в циклеfor...of, выводя результаты. Программа выводит:Зелье лечения: пусто Зелье маны: остаток 0 Свиток света: вы читаете заклинание Свет