Статьи

TypeScript для начинающих, часть 4: классы

Мы прошли долгий путь в изучении TypeScript с начала этой серии. В первом уроке вы кратко рассказали о TypeScript и предложили несколько IDE, которые вы можете использовать для написания TypeScript. Во втором учебнике рассматриваются типы данных , а в третьем учебнике рассматриваются основы интерфейсов в TypeScript .

Как вы, возможно, уже знаете, JavaScript только недавно добавил встроенную поддержку классов и объектно-ориентированного программирования. Однако TypeScript позволил разработчикам использовать классы в своем коде в течение длительного времени. Этот код затем компилируется в JavaScript, который будет работать во всех основных браузерах. В этом уроке вы узнаете о классах в TypeScript. Они похожи на своих аналогов в ES6, но строже.

Давайте начнем с основ. Классы являются фундаментальной частью объектно-ориентированного программирования. Вы используете классы для представления любой сущности, которая имеет некоторые свойства и функции, которые могут воздействовать на заданные свойства. TypeScript дает вам полный контроль над свойствами и функциями, которые доступны внутри и вне их собственного содержащего класса. Вот очень простой пример создания класса Person .

01
02
03
04
05
06
07
08
09
10
11
12
13
class Person {
    name: string;
    constructor(theName: string) {
        this.name = theName;
    }
    introduceSelf() {
        console.log(«Hi, I am » + this.name + «!»);
    }
}
 
let personA = new Person(«Sally»);
 
personA.introduceSelf();

Приведенный выше код создает очень простой класс с именем Person . Этот класс имеет свойство с именем name и функцию под названием introduceSelf . Класс также имеет конструктор, который также является в основном функцией. Тем не менее, конструкторы особенные, потому что они вызываются каждый раз, когда мы создаем новый экземпляр нашего класса.

Вы также можете передать параметры конструкторам для инициализации различных свойств. В нашем случае мы используем конструктор для инициализации имени человека, которого мы создаем с помощью класса Person . Функция introduceSelf является методом класса Person , и мы используем его здесь, чтобы вывести имя человека на консоль. Все эти свойства, методы и конструктор класса все вместе называются членами класса.

Следует помнить, что класс Person не создает человека автоматически. Это больше похоже на план со всей информацией об атрибутах, которые человек должен был когда-то создать. Имея это в виду, мы создали нового человека и назвали ее Салли. При вызове метода introduceSelf для этого человека будет напечатана строка «Привет, я Салли!» на консоль.

В предыдущем разделе мы создали человека по имени Салли. Прямо сейчас в любом месте нашего кода можно изменить имя человека с Салли на Минди, как показано в следующем примере.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
class Person {
    name: string;
    constructor(theName: string) {
        this.name = theName;
    }
    introduceSelf() {
        console.log(«Hi, I am » + this.name + «!»);
    }
}
 
let personA = new Person(«Sally»);
 
// Prints «Hi, I am Sally!»
personA.introduceSelf();
 
personA.name = «Mindy»;
 
// Prints «Hi, I am Mindy!»
personA.introduceSelf();

Возможно, вы заметили, что мы смогли использовать как свойство name и метод ввестиSelf за пределами содержащего класса. Это связано с тем, что по умолчанию все члены класса в TypeScript являются public . Вы также можете явно указать, что свойство или метод является общедоступным, добавив перед ним ключевое слово public .

Иногда вы не хотите, чтобы свойство или метод были доступны вне его содержащего класса. Этого можно достичь, сделав этих участников приватными, используя ключевое слово private . В приведенном выше коде мы могли бы сделать свойство name private и предотвратить его изменение вне класса, в котором он содержится. После этого изменения TypeScript покажет вам ошибку, сообщающую, что свойство name является private и вы можете получить к нему доступ только внутри класса Person . На приведенном ниже снимке экрана показана ошибка в коде Visual Studio.

Частная собственность не доступна за пределами своего класса

Наследование позволяет создавать более сложные классы, начиная с базового класса. Например, мы можем использовать класс Person из предыдущего раздела в качестве основы для создания класса Friend котором будут все члены Person и добавлены некоторые его собственные члены. Точно так же вы можете добавить класс Family или Teacher .

Все они наследуют методы и свойства Person , добавляя при этом некоторые собственные методы и свойства, чтобы выделить их отдельно. Следующий пример должен прояснить ситуацию. Я также добавил код для класса Person здесь, чтобы вы могли легко сравнить код как базового класса, так и производного класса.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Person {
    private name: string;
    constructor(theName: string) {
        this.name = theName;
    }
    introduceSelf() {
        console.log(«Hi, I am » + this.name + «!»);
    }
}
 
class Friend extends Person {
    yearsKnown: number;
    constructor(name: string, yearsKnown: number) {
        super(name);
        this.yearsKnown = yearsKnown;
    }
    timeKnown() {
        console.log(«We have been friends for » + this.yearsKnown + » years.»)
    }
}
 
let friendA = new Friend(«Jacob», 6);
 
// Prints: Hi, I am Jacob!
friendA.introduceSelf();
 
// Prints: We have been friends for 6 years.
friendA.timeKnown();

Как видите, вы должны использовать ключевое слово extends для класса Friend чтобы наследовать всех членов класса Person . Важно помнить, что конструктор производного класса должен всегда вызывать конструктор базового класса с вызовом super() .

Возможно, вы заметили, что конструктору Friend не нужно иметь такое же количество параметров, как у базового класса. Однако первый параметр имени был передан в super() для вызова конструктора родителя, который также принял один параметр. Нам не нужно было переопределять функцию ввестиSelf внутри класса Friend потому что она была унаследована от класса Person .

До этого момента мы делали членов класса только private или public . Делая их общедоступными, мы можем получить к ним доступ из любого места, а закрытые члены ограничивают их своим собственным классом. Иногда вы можете захотеть, чтобы члены базового класса были доступны внутри всех производных классов.

В таких случаях вы можете использовать protected модификатор, чтобы ограничить доступ члена только к производным классам. Вы также можете использовать protected ключевое слово с конструктором базового класса. Это не позволит никому создать экземпляр этого класса. Однако вы все равно сможете расширять классы на основе этого базового класса.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Person {
    private name: string;
    protected age: number;
    protected constructor(theName: string, theAge: number) {
        this.name = theName;
        this.age = theAge;
    }
    introduceSelf() {
        console.log(«Hi, I am » + this.name + «!»);
    }
}
 
class Friend extends Person {
    yearsKnown: number;
    constructor(name: string, age: number, yearsKnown: number) {
        super(name, age);
        this.yearsKnown = yearsKnown;
    }
    timeKnown() {
        console.log(«We have been friends for » + this.yearsKnown + » years.»)
    }
    friendSince() {
        let firstAge = this.age — this.yearsKnown;
        console.log(`We have been friends since I was ${firstAge} years old.`)
    }
}
 
let friendA = new Friend(«William», 19, 8);
 
 
// Prints: We have been friends since I was 11 years old.
friendA.friendSince();

В приведенном выше коде вы можете видеть, что мы сделали свойство age protected . Это предотвращает использование age вне любых классов, производных от Person . Мы также использовали ключевое слово protected для конструктора класса Person . Объявление конструктора как protected означает, что мы больше не сможем напрямую создавать экземпляр класса Person . На следующем снимке экрана показана ошибка, которая появляется при попытке создать экземпляр класса с помощью protected конструктора.

TypeScript защищенный конструктор

В этом уроке я попытался охватить основы классов в TypeScript. Мы начали учебник с создания базового класса Person который выводил имя человека на консоль. После этого вы узнали о private ключевом слове, которое можно использовать для предотвращения доступа к членам класса в любой произвольной точке программы.

Наконец, вы узнали, как расширять различные классы в вашем коде, используя базовый класс с наследованием. Есть много всего, что вы можете узнать о классах в официальной документации .

Если у вас есть какие-либо вопросы, связанные с этим руководством, дайте мне знать в комментариях.