abstract în TypeScript

Clase TypeScript 1.6

O clasă abstract nu poate fi instanțiată; metodele abstract trebuie implementate în clasele derivate.

Sintaxă
abstract class Baza {
    abstract metoda(): Tip;     // fără corp
    comun(): void { ... }        // cu corp
}
class Concret extends Baza {
    metoda(): Tip { ... }
}

Ce face abstract

O clasă abstract este o bază pentru alte clase. Nu poți crea obiecte direct din ea cu new; poți doar s-o extinzi. Poate avea metode obișnuite, cu cod comun, și metode abstract, fără corp, pe care fiecare clasă derivată este obligată să le scrie.

Este potrivită când mai multe clase au o parte de cod comună și o parte care diferă: clasa abstractă scrie partea comună și declară partea care diferă. Față de o interfață, o clasă abstractă poate conține cod și câmpuri cu valori; față de o clasă obișnuită, garantează că nimeni nu uită să implementeze metodele cerute.

Și câmpurile și accesorii pot fi abstract. Tipul unei clase abstracte ca valoare se scrie abstract new () => T.

Exemple

Exemplul 1: Bază comună pentru forme

descriere() este scrisă o singură dată și folosește arie(), implementată diferit în fiecare clasă.

abstract class Forma {
    constructor(readonly nume: string) {}
    abstract arie(): number;

    descriere(): string {
        return `${this.nume}: ${this.arie().toFixed(2)} cm²`;
    }
}

class Cerc extends Forma {
    constructor(private raza: number) {
        super("cerc");
    }
    arie(): number {
        return Math.PI * this.raza ** 2;
    }
}

class Dreptunghi extends Forma {
    constructor(private l: number, private h: number) {
        super("dreptunghi");
    }
    arie(): number {
        return this.l * this.h;
    }
}

const forme: Forma[] = [new Cerc(2), new Dreptunghi(3, 4)];
for (const f of forme) console.log(f.descriere());

Rezultat

cerc: 12.57 cm²
dreptunghi: 12.00 cm²

Exemplul 2: Clasa abstractă nu se poate instanția

abstract class Forma {
    abstract arie(): number;
}
const f = new Forma();
console.log(f);

Eroarea afișată de tsc

exemplu.mts(4,11): error TS2511: Cannot create an instance of an abstract class.

Exemplul 3: Metodă abstractă neimplementată

abstract class Forma {
    abstract arie(): number;
    abstract perimetru(): number;
}
class Patrat extends Forma {
    constructor(private l: number) {
        super();
    }
    arie() {
        return this.l ** 2;
    }
}
console.log(new Patrat(2).arie());

Eroarea afișată de tsc

exemplu.mts(5,7): error TS2515: Non-abstract class 'Patrat' does not implement inherited abstract member perimetru from class 'Forma'.

Greșeli frecvente

  • Faci abstractă o clasă care nu are cod comun. O interfață este mai simplă și nu generează cod.
  • Uiți super(...) în constructorul clasei derivate. tsc dă Constructors for derived classes must contain a ‘super’ call.

Comenzi înrudite

  • extends: O clasă moștenește câmpurile și metodele altei clase; o interfață preia proprietățile altor interfețe.
  • implements: O clasă promite că respectă una sau mai multe interfețe; tsc verifică dacă are toți membrii ceruți.
  • class: Clasele din JavaScript, cu tipuri pe câmpuri, constructor și metode, plus modificatori de acces și interfețe.
  • override: Marchează o metodă care rescrie o metodă din clasa de bază; tsc dă eroare dacă metoda de bază nu există.
  • interface: Descrie forma unui obiect: ce proprietăți are, de ce tip sunt și ce metode are.