Menu

TypeScript abstrakte Klasse: Methoden, Eigenschaften, vs Interface

Eine abstrakte Klasse in TypeScript ist eine Basisklasse, die nicht instanziiert werden kann und Methoden den Unterklassen zur Implementierung überlassen kann. Abstrakte Methoden und Eigenschaften, das Template-Method-Muster, abstrakte Konstruktortypen und wann ein Interface die bessere Wahl ist.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Eine abstrakte Klasse ist eine als abstract markierte Basisklasse. Sie kann nicht mit new erzeugt werden, und sie kann abstract Methoden ohne Rumpf deklarieren, die jede Unterklasse implementieren muss.

Shape teilt describe() mit jeder Unterklasse und zwingt jede, area() bereitzustellen. Der Typ Shape[] fasst jede Mischung aus Unterklassen.

Eine abstrakte Klasse kann nicht instanziiert werden

new auf einer abstrakten Klasse aufzurufen ist ein Compilerfehler, denn das Objekt hätte Methoden ohne Implementierung:

index.ts(6,11): error TS2511: Cannot create an instance of an abstract class.

Das ist eine Regel beim Kompilieren. abstract wird aus der Ausgabe entfernt, das erzeugte Shape ist also eine gewöhnliche JavaScript-Klasse, und untypisierter JavaScript-Code könnte weiterhin new Shape() aufrufen. Braucht eine Bibliothek einen Schutz zur Laufzeit, kann der Konstruktor new.target prüfen:

Abstrakte Methoden und Eigenschaften

Eine Unterklasse muss jeden abstrakten Member implementieren oder selbst abstrakt sein. Fehlt einer, ist das der Fehler TS2515, der etwa lautet Non-abstract class 'Square' does not implement inherited abstract member area from class 'Shape', oder TS2654, der alle aufzählt, wenn mehrere fehlen.

Felder, Getter und Methoden können alle abstrakt sein, und sie können protected sein:

Eine abstrakte Methode hat keinen Rumpf; einen zu schreiben ist der Fehler TS1245 (Method 'x' cannot have an implementation because it is marked abstract). Eine abstrakte Klasse muss überhaupt keine abstrakten Member haben: abstract allein verhindert nur die direkte Instanziierung.

Das Template-Method-Muster

Der häufigste Grund für eine abstrakte Klasse: Die Basisklasse legt die Reihenfolge der Schritte fest, und jede Unterklasse füllt die Schritte aus, die sich unterscheiden.

Abstrakte Klassen können generisch sein, wie hier, sodass jede Unterklasse den Datensatztyp wählt.

Abstrakte Konstruktortypen

typeof Shape ist bei einer abstrakten Klasse ein Konstruktor, den du nicht aufrufen darfst, ein Parameter vom Typ typeof Shape kann also kein new c() ausführen. Soll eine Funktion abstrakte Klassen akzeptieren (etwa um sie zu registrieren oder instanceof zu prüfen), typisierst du sie mit einer abstrakten Construct Signature:

abstract new akzeptiert abstrakte und konkrete Klassen; einfaches new akzeptiert nur konkrete.

Abstrakte Klasse vs Interface

Abstrakte KlasseInterface
Enthält Codeja: Methoden, Feldinitialisierer, Konstruktornein, nur Typen
Existiert zur Laufzeitjanein, entfernt
instanceoffunktioniertnicht möglich
Eine Klasse kann verwendeneine (extends)viele (implements)
Zugriffsmodifikatorenprivate, protected, publicnur öffentliche Member
Typ für einfache Objektenur ohne private/protected Member, und instanceof scheitert dannja, jeder Wert mit der Form

Die Faustregel: ein Interface, wenn du nur eine Form beschreiben musst (der häufigste Fall, und er funktioniert auch für Objektliterale), eine abstrakte Klasse, wenn Unterklassen echte Implementierung teilen und der Compiler sie zwingen soll, die Lücken zu füllen. Beides lässt sich gut kombinieren: ein Interface für den öffentlichen Vertrag, eine abstrakte Klasse als bequeme Basis, die es implementiert. Den anderen häufigen Vergleich findest du unter interface vs type.

Häufige Fehler

  • Eine abstrakte Klasse verwenden, wo ein Interface reicht. Hat die Basisklasse keinen Code, ist sie ein Interface mit zusätzlichem Gewicht zur Laufzeit und der Grenze der Einfachvererbung.
  • static abstract versuchen. Nicht erlaubt. Statische Member können nicht abstrakt sein.
  • Einen Laufzeitfehler bei new auf einer abstrakten Klasse erwarten. Es gibt keinen, außer du schreibst die Prüfung mit new.target.
  • Eine abstrakte Methode im Basiskonstruktor aufrufen. Sie läuft, bevor die Felder der Unterklasse initialisiert sind, also sieht die Implementierung sie als undefined.

Häufig gestellte Fragen

Was ist eine abstrakte Klasse in TypeScript?

Eine als abstract markierte Klasse, die nicht mit new erzeugt werden kann und abstract Member ohne Implementierung deklarieren darf. Unterklassen müssen jeden abstrakten Member implementieren. So teilt man Code und verlangt zugleich eine Form.

Was ist der Unterschied zwischen einer abstrakten Klasse und einem Interface in TypeScript?

Eine abstrakte Klasse kann echten Code enthalten (implementierte Methoden, Felder mit Startwerten, einen Konstruktor) und existiert zur Laufzeit, also funktioniert instanceof damit; eine Klasse kann nur eine erweitern. Ein Interface hat keinen Code, wird beim Kompilieren entfernt, und eine Klasse kann viele implementieren. Nimm eine abstrakte Klasse, um Verhalten zu teilen, und ein Interface, um eine Form zu beschreiben.

Kann eine abstrakte Klasse in TypeScript einen Konstruktor haben?

Ja. Er läuft, wenn eine Unterklasse super(...) aufruft. new auf der abstrakten Klasse selbst kannst du trotzdem nicht aufrufen (TS2511: Cannot create an instance of an abstract class).

Können statische Methoden in TypeScript abstrakt sein?

Nein. abstract gilt nur für Instanzmember; static abstract ist der Fehler TS1243 ('static' modifier cannot be used with 'abstract' modifier). Um eine statische Form zu verlangen, typisierst du den Konstruktor mit einem Interface, das den statischen Member enthält, und prüfst die Klasse dagegen.

Wird eine abstrakte Klasse zur Laufzeit durchgesetzt?

Nein. abstract wird entfernt, die kompilierte Klasse ist also gewöhnliches JavaScript, und reiner JavaScript-Code könnte weiterhin new darauf aufrufen. Wenn das wichtig ist, prüfe im Konstruktor new.target und wirf.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S