Klasy w TypeScript

Ten artykuł wyjaśnia klasy w TypeScript.

YouTube Video

Klasy w TypeScript

Klasy w TypeScript opierają się na klasach ES6 z JavaScript i oferują dodatkowe funkcje, takie jak adnotacje typów i modyfikatory dostępu. Pozwala to na wykorzystanie koncepcji programowania obiektowego, przy jednoczesnym zapewnieniu większego bezpieczeństwa typów i przejrzystości.

Poniżej znajdują się wyjaśnienia podstawowego użycia i funkcji klas w TypeScript.

Podstawowa definicja klasy

 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 i age to właściwości (zmienne członkowskie) klasy.
  • constructor to metoda wywoływana podczas tworzenia instancji klasy, która przyjmuje argumenty i przypisuje wartości właściwościom.
  • greet to metoda klasy, która wskazuje, że nie zwraca żadnej wartości, ponieważ ma typ void.

Modyfikatory dostępu

W TypeScript można używać modyfikatorów dostępu (public, private, protected), aby kontrolować dostęp do właściwości i metod klasy.

public

Domyślnie wszystkie właściwości i metody są public. Oznacza to, że można uzyskać do nich dostęp z zewnątrz klasy.

 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.
  • Właściwość species i metoda makeSound są zadeklarowane jako public, dzięki czemu są dostępne spoza klasy.

private

Użycie modyfikatora private uniemożliwia dostęp do właściwości lub metod spoza klasy.

 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
  • Właściwość brand jest zadeklarowana jako private, więc nie można jej używać spoza klasy.
  • Enkapsulację danych można osiągnąć przez ukrywanie właściwości z użyciem modyfikatora private.

protected

Modyfikator protected ogranicza dostęp z zewnątrz klasy, ale pozwala na dostęp w klasach pochodnych (podklasach).

 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.
  • Właściwość model jest zadeklarowana jako protected, więc nie można jej używać spoza klasy, ale jest dostępna w klasach pochodnych.

Gettery i Settery

W TypeScript można definiować gettery i settery, używając słów kluczowych get i set, aby pobierać i ustawiać wartości właściwości.

 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.
  • W tym przykładzie dla właściwości salary używany jest getter i setter, aby kontrolować zewnętrzny dostęp i modyfikacje. Setter wykonuje walidację, aby zapobiec wartościom ujemnym, i wyświetla ostrzeżenie w przypadku podania nieprawidłowej wartości.

Dziedziczenie

W TypeScript klasy mogą być dziedziczone. Używając słowa kluczowego extends, można dziedziczyć funkcjonalność z klasy bazowej.

 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.
  • W tym przykładzie klasa Bird dziedziczy po klasie Animal, co pozwala jej korzystać z metody move klasy Animal. Ponadto definiuje własną metodę fly, dodając nową funkcjonalność przy jednoczesnym dziedziczeniu cech klasy nadrzędnej.

Klasy abstrakcyjne

Klasy abstrakcyjne (abstract) nie mogą być instancjonowane bezpośrednio i są używane jako szablony do dostarczania konkretnych implementacji w podklasach.

 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.
  • W tym przykładzie Shape jest zdefiniowana jako klasa abstrakcyjna, a getArea to metoda abstrakcyjna, którą muszą zaimplementować klasy pochodne. Klasa Circle dziedziczy po tej klasie abstrakcyjnej i implementuje własną metodę getArea do obliczania pola koła. Dodatkowo, konkretne metody takie jak describe są dziedziczone jako wspólna funkcjonalność i mogą być używane bez zmian.

Związek z interfejsami

Klasy mogą implementować interfejsy, zapewniając, że mają określone właściwości i metody.

 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.
  • W tym przykładzie interfejs Flyable definiuje specyfikację metody fly, a klasa Airplane implementuje ten interfejs, dostarczając konkretną definicję metody fly. Dzięki temu każdy obiekt traktowany jako typ Flyable ma gwarancję posiadania metody fly.

Pola statyczne

Gdy definiujesz pola statyczne w klasie, te metody i właściwości są powiązane bezpośrednio z klasą jako taką. Pola statyczne można wywoływać bez tworzenia instancji klasy.

 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
  • Metody statyczne definiujesz za pomocą słowa kluczowego static.
  • W tym przykładzie klasa MathUtils definiuje statyczną metodę add oraz statyczną właściwość PI.
  • Pola statyczne nie należą do instancji klasy, lecz można je wywołać bezpośrednio z poziomu samej klasy.

Podsumowanie

Klasy TypeScript dodają do funkcjonalności klas JavaScript takie funkcje jak bezpieczeństwo typów, modyfikatory dostępu oraz klasy abstrakcyjne. To umożliwia bardziej zaawansowane i bezpieczniejsze programowanie obiektowe.

Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.

YouTube Video