Angular - klasy abstrakcyjne w TypeScript-cie

Stronę tą wyświetlono już: 1070 razy

TypeScript umożliwia deklarowanie klas abstrakcyjnych, czyli takich, których obiektu nie da się utworzyć. A na cóż taka klasa komu. Otóż na to, aby klasy dziedziczące po takiej klasie, które współdzielą pewne cechy własne i metody również mogły być traktowane tak, jakby były obiektem tego samego typu. Innymi słowy chodzi tutaj o polimorfizm (wielopostaciowość), gdzie dwa różne typy obiektów na tą samą akcję wykonują różne działania. Takim klasycznym przykładem polimorfizmu (przytaczanym wszędzie gdzie się da jako przykład) jest stary znany przykład z klasą opisującą figury geometryczne. Nawiązując więc do tego pokażę taki klasyczny przykładzik abstrakcyjnej klasy w TypeScript-cie:

Listing 1
  1. abstract class Figure {
  2. protected pFigureName: string; // to pole będzie współdzielone przez wszystkie klasy dziedziczące po klasie Figure
  3. abstract get surfaceArea(): number; // ten abstrakcyjny getter zwraca pole powierzchni
  4. abstract get circuit(): number; // ten abstrakcyjny getter zwraca obwód
  5. get figureName(): string { return this.pFigureName; } // ten getter zwraca nazwę figury geometrycznej
  6. }

Próba utworzenia instancji klasy abstrakcyjnej powinna się zakończyć wyświetleniem komunikatu błędu:

Cannot create an instance of an abstract class.

Co jakby nie patrzeć jest poprawnym zachowaniem.

Utwórzmy więc dwie klasy:

  • Circle - koło
    Listing 2
    1. class Circle extends Figure {
    2. ray: number;
    3. constructor(ray: number) {
    4. super();
    5. this.ray = ray;
    6. this.pFigureName = 'circle';
    7. }
    8. get surfaceArea(): number {
    9. return this.ray * this.ray * Math.PI;
    10. }
    11. get circuit(): number {
    12. return this.ray * 2 * Math.PI;
    13. }
    14. }
  • Rectangle - prostokąt
    Listing 3
    1. class Rectangle extends Figure {
    2. width: number;
    3. height: number;
    4. constructor(width: number, height: number) {
    5. super();
    6. this.width = width;
    7. this.height = height;
    8. this.pFigureName = 'rectangle';
    9. }
    10. get surfaceArea(): number {
    11. return this.width * this.height;
    12. }
    13. get circuit(): number {
    14. return this.width * 2 + this.height * 2;
    15. }
    16. }

A teraz czas na małą polimorficzną sztuczkę. Otóż teraz mogę różne obiekty będące figurami i dziedziczące po klasie abstrakcyjnej Figure przechowywać w jednej tablicy obiektów typu Figure. Co by nie być gołosłownym oto i przykład takiej tablicy:

Listing 4
  1. figuresTable: Figure[] = [];
  2. figuresTable.push(new Circle(100));
  3. figuresTable.push(new Rectangle(100, 200));
  4. figuresTable.forEach((figure) => console.log('Nazwa figury: ', figure.figureName, ' Obwód: ', figure.circuit, ' Pole powierzchni: ', figure.surfaceArea));

Powyższy kod powinien wyświetlić w konsoli:

Nazwa figury:  circle  Obwód:  628.3185307179587  Pole powierzchni:  31415.926535897932 chess.component.ts:122:54
Nazwa figury:  rectangle  Obwód:  600  Pole powierzchni:  20000
Propozycje książek

Komentarze