implements
In der Lektion Objekttypen hast du Interfaces verwendet, um die Form eines Objekts zu beschreiben. Ein Interface kann auch Methoden enthalten. Bei einer Methode schreibst du Namen, Parameter und Rückgabetyp, ohne Rumpf:
interface Figur {
name: string;
angreifen(): number;
}Jede Figur hat einen Namen und eine Methode angreifen, die eine Zahl zurückgibt, den Schaden. Das Spiel kann dann mit jeder Figur arbeiten, egal welche Klasse sie hat: function kaempfe(gruppe: Figur[]).
Eine Klasse kann versprechen, diese Form zu haben: class Zauberer implements Figur. TypeScript prüft die Klasse dann gleich dort, wo sie deklariert ist, und wenn das Versprechen nicht gehalten wird, bekommst du einen Fehler:
interface Figur {
name: string;
angreifen(): number;
}
class Zauberer implements Figur {
name: string;
mana: number = 30;
constructor(name: string) {
this.name = name;
}
}TypeScript meldet:
main.ts(6,7): error TS2420: Class 'Zauberer' incorrectly implements interface 'Figur'.
Property 'angreifen' is missing in type 'Zauberer' but required in type 'Figur'.Die erste Zeile sagt, welche Klasse nicht zu welchem Interface passt; die eingerückte Zeile sagt, warum: angreifen fehlt. Füge der Klasse die Methode hinzu, und der Fehler verschwindet:
angreifen(): number {
return this.mana / 2;
}implements gibt der Klasse nichts: Du schreibst weiterhin jedes Feld und jede Methode selbst. Es ist eine Prüfung und auch ein Hinweis für alle, die den Code lesen: „Diese Klasse soll eine Figur sein.“ Hat eine Methode den falschen Typ, sagt TypeScript es dir ebenfalls. Gibt angreifen einen Text zurück, bekommst du Property 'angreifen' in type 'Zauberer' is not assignable to the same property in base type 'Figur'. (TS2416).
Formen, nicht Namen. TypeScript vergleicht Formen, also ist jedes Objekt mit einem name und einer Methode angreifen eine Figur, auch ohne implements, sogar ein einfaches Objekt:
interface Figur {
name: string;
angreifen(): number;
}
class Zauberer implements Figur {
name: string;
mana: number = 30;
constructor(name: string) {
this.name = name;
}
angreifen(): number {
return this.mana / 2;
}
}
class Bogenschuetze {
name: string = "Kira";
angreifen(): number {
return 7;
}
}
const gruppe: Figur[] = [new Zauberer("Lena"), new Bogenschuetze(), { name: "Bruno", angreifen: () => 9 }];
for (const mitglied of gruppe) {
console.log(`${mitglied.name}: ${mitglied.angreifen()}`);
}Das gibt aus:
Lena: 15
Kira: 7
Bruno: 9Bogenschuetze sagt nicht implements Figur, passt aber, also kann er ins Array. Mit implements erfährst du allerdings schon bei der Klasse selbst, dass etwas fehlt, und nicht irgendwo später, wo du sie zum ersten Mal als Figur verwendest. Und über den Typ Figur kannst du nur verwenden, was das Interface hat: gruppe[0].mana ergibt Property 'mana' does not exist on type 'Figur'. (TS2339), obwohl der Zauberer mana hat.
So schreibst du es:
Anweisungen
- 1
Schreibe eine Klasse
Magier, dieFigurimplementiert. Sie hat die Feldernameundmana(eine Zahl), einen Konstruktor, der beide setzt, und eine Methodeangreifen(), diemanamal 3 zurückgibt. - 2
Füge
new Magier("Lena", 5)zum Arraygruppehinzu. Das Programm gibt aus:Bruno richtet 12 Schaden an Lena richtet 15 Schaden an - 3
Jede Figur soll sich auch vorstellen können. Füge dem Interface
Figurdie Zeilebeschreibe(): string;hinzu. TypeScript meldet dann beide Klassen, schreibe also die Methode in jede von ihnen: Sie gibt den Namen gefolgt von, der Kriegeroder, die Magierinzurück. Füge unter der Schleife eine zweite Schleife übergruppehinzu, diemitglied.beschreibe()ausgibt. Das Programm gibt aus:Bruno richtet 12 Schaden an Lena richtet 15 Schaden an Bruno, der Krieger Lena, die Magierin