Классы в TypeScript

Классы в TypeScript

В этой статье объясняются классы в TypeScript.

YouTube Video

Классы в TypeScript

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

Ниже приведены объяснения основного использования и особенностей классов в TypeScript.

Основное определение класса

 1class Person {
 2    name: string;  // Member variable
 3    age: number;   // Member variable
 4
 5    // Constructor
 6    constructor(name: string, age: number) {
 7        this.name = name;
 8        this.age = age;
 9    }
10
11    // Method
12    greet(): void {
13        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
14    }
15}
16
17const person = new Person("Alice", 25);
18person.greet();  // Hello, my name is Alice and I am 25 years old.
  • name и age являются свойствами (переменными-членами) класса.
  • constructor — это метод, вызываемый при создании экземпляра класса, который принимает аргументы и присваивает значения свойствам.
  • greet — это метод класса, который указывает, что он не возвращает значение, так как имеет тип void.

Модификаторы доступа

В TypeScript вы можете использовать модификаторы доступа (public, private, protected) для управления доступом к свойствам и методам класса.

public

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

 1class Animal {
 2    public species: string;
 3
 4    constructor(species: string) {
 5        this.species = species;
 6    }
 7
 8    public makeSound(): void {
 9        console.log(`${this.species} makes a sound.`);
10    }
11}
12
13const animal = new Animal("Dog");
14console.log(animal.species);  // Dog
15animal.makeSound();           // Dog makes a sound.
  • Свойство species и метод makeSound объявлены как public, поэтому они доступны извне класса.

private

Использование модификатора private предотвращает доступ к свойствам или методам из-за пределов класса.

 1class Car {
 2    private brand: string;
 3
 4    constructor(brand: string) {
 5        this.brand = brand;
 6    }
 7
 8    public getBrand(): string {
 9        return this.brand;
10    }
11}
12
13const car = new Car("Toyota");
14// console.log(car.brand);  // Error: 'brand' is private and cannot be accessed.
15console.log(car.getBrand());  // Toyota
  • Свойство brand объявлено как private, поэтому оно недоступно из вне класса.
  • Инкапсулирование данных достигается путем скрытия свойств с помощью модификатора private.

protected

Модификатор protected ограничивает доступ из-за пределов класса, но разрешает его в подклассах (производных классах).

 1class Vehicle {
 2    protected model: string;
 3
 4    constructor(model: string) {
 5        this.model = model;
 6    }
 7}
 8
 9class Truck extends Vehicle {
10    public getModel(): string {
11        return this.model;
12    }
13}
14
15const truck = new Truck("Ford F-150");
16console.log(truck.getModel());  // Ford F-150
17
18// console.log(truck.model);
19// Error: Property 'model' is protected and only accessible within class 'Vehicle' and its subclasses.
  • Свойство model объявлено как protected, поэтому оно недоступно извне класса, но доступно в подклассах.

Геттеры и сеттеры

В TypeScript вы можете определять геттеры и сеттеры с помощью ключевых слов get и set для получения и задания значений свойств.

 1class Employee {
 2    private _salary: number;
 3
 4    constructor(salary: number) {
 5        this._salary = salary;
 6    }
 7
 8    // Getter
 9    get salary(): number {
10        return this._salary;
11    }
12
13    // Setter
14    set salary(newSalary: number) {
15        if (newSalary > 0) {
16            this._salary = newSalary;
17        } else {
18            console.log("Salary must be positive.");
19        }
20    }
21}
22
23const employee = new Employee(50000);
24console.log(employee.salary);  // 50000
25employee.salary = 60000;
26console.log(employee.salary);  // 60000
27employee.salary = -100;        // Salary must be positive.
  • В этом примере для свойства salary используется геттер и сеттер для контроля внешнего доступа и изменений. Сеттер выполняет валидацию для предотвращения отрицательных значений и выводит предупреждающее сообщение, если указано некорректное значение.

Наследование

В TypeScript классы могут наследоваться. С помощью ключевого слова extends вы можете наследовать функциональность от родительского класса.

 1class Animal {
 2    constructor(public name: string) {}
 3
 4    public move(): void {
 5        console.log(`${this.name} is moving.`);
 6    }
 7}
 8
 9class Bird extends Animal {
10    public fly(): void {
11        console.log(`${this.name} is flying.`);
12    }
13}
14
15const bird = new Bird("Sparrow");
16bird.move();  // Sparrow is moving.
17bird.fly();   // Sparrow is flying.
  • В этом примере класс Bird наследуется от класса Animal, что позволяет использовать метод move из класса Animal. Кроме того, он определяет собственный метод fly, добавляя новую функциональность при наследовании особенностей родительского класса.

Абстрактные классы

Абстрактные классы (abstract) не могут быть созданы напрямую и используются как шаблоны для предоставления конкретных реализаций в подклассах.

 1abstract class Shape {
 2    abstract getArea(): number;
 3
 4    public describe(): void {
 5        console.log("This is a shape.");
 6    }
 7}
 8
 9class Circle extends Shape {
10    constructor(private radius: number) {
11        super();
12    }
13
14    public getArea(): number {
15        return Math.PI * this.radius * this.radius;
16    }
17}
18
19const circle = new Circle(5);
20console.log(circle.getArea());  // 78.53981633974483
21circle.describe();  // This is a shape.
  • В этом примере Shape определён как абстрактный класс, а getArea — это абстрактный метод, который должен быть реализован в подклассах. Класс Circle наследует этот абстрактный класс и реализует свой собственный метод getArea для вычисления площади круга. Кроме того, конкретные методы, такие как describe, наследуются как общая функциональность и могут использоваться без изменений.

Связь с интерфейсами

Классы могут реализовывать интерфейсы, обеспечивая наличие определенных свойств и методов.

 1interface Flyable {
 2    fly(): void;
 3}
 4
 5class Airplane implements Flyable {
 6    public fly(): void {
 7        console.log("The airplane is flying.");
 8    }
 9}
10
11const airplane: Flyable = new Airplane();
12airplane.fly();  // The airplane is flying.
  • В этом примере интерфейс Flyable определяет спецификацию для метода fly, а класс Airplane реализует этот интерфейс, предоставляя конкретную реализацию метода fly. Таким образом, любой объект, который может рассматриваться как тип Flyable, гарантированно будет иметь метод fly.

Статические члены

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

 1class MathUtils {
 2    static PI: number = 3.14;
 3
 4    static add(a: number, b: number): number {
 5        return a + b;
 6    }
 7}
 8
 9console.log(MathUtils.add(10, 20)); // 30
10console.log(MathUtils.PI); // 3.14
  • Статические методы определяются с помощью ключевого слова static.
  • В этом примере класс MathUtils определяет статический метод add и статическое свойство PI.
  • Статические члены не принадлежат экземплярам класса, но могут вызываться напрямую от имени самого класса.

Резюме

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

Вы можете следовать этой статье, используя Visual Studio Code на нашем YouTube-канале. Пожалуйста, также посмотрите наш YouTube-канал.

YouTube Video