Ich würde gerne wissen, was Mann und Kind gemeinsam haben und wie sie sich unterscheiden.
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Ich würde gerne wissen, was Mann und Kind gemeinsam haben und wie sie sich unterscheiden.
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Antworten:
extends
meint:Die neue Klasse ist ein Kind . Es bringt Vorteile mit der Vererbung. Es hat alle Eigenschaften und Methoden als übergeordnetes Element. Es kann einige davon überschreiben und neue implementieren, aber das übergeordnete Material ist bereits enthalten.
implements
meint:Die neue Klasse kann als dieselbe "Form" behandelt werden , obwohl sie kein Kind ist . Es kann an jede Methode übergeben werden, bei der dies Person
erforderlich ist, unabhängig davon, ob ein anderes übergeordnetes Element als vorhanden istPerson
In OOP (Sprachen wie C #, Java) würden wir verwenden
extends
von der Vererbung profitieren (siehe Wiki ). Kleines Zitat:
... Die Vererbung in den meisten klassenbasierten objektorientierten Sprachen ist ein Mechanismus, bei dem ein Objekt alle Eigenschaften und Verhaltensweisen des übergeordneten Objekts erfasst. Durch Vererbung können Programmierer: Klassen erstellen, die auf vorhandenen Klassen aufbauen ...
implements
wird mehr für Polymorphismus sein (siehe Wiki ). Kleines Zitat:
... Polymorphismus ist die Bereitstellung einer einzigen Schnittstelle zu Entitäten verschiedener Typen ...
Wir können also einen wirklich anderen Vererbungsbaum von uns haben class Man
.
class Man extends Human ...
aber wenn wir auch erklären, dass wir vorgeben können, ein anderer Typ zu sein - Person
:
class Man extends Human
implements Person ...
.. dann können wir es überall verwenden, wo das Person
benötigt wird. Wir müssen nur die von Personen erfüllen "interface"
(dh alle öffentlichen Dinge implementieren) .
implement
andere Klasse? Das ist wirklich cooles ZeugDas schöne Gesicht von Javascript (einer der Vorteile) ist die integrierte Unterstützung der Enten-Eingabe ( siehe Wiki ). Kleines Zitat:
"Wenn es wie eine Ente läuft und wie eine Ente quakt, dann muss es eine Ente sein."
Wenn also in Javascript zwei verschiedene Objekte ... eine ähnliche Methode haben (z. B. render()
) , können sie an eine Funktion übergeben werden, die dies erwartet:
function(engine){
engine.render() // any type implementing render() can be passed
}
Um das nicht zu verlieren - wir können in Typescript dasselbe tun - mit mehr typisierter Unterstützung. Und dort ist
class implements class
hat seine Rolle, wo es Sinn macht
In OOP-Sprachen als C#
... keine Möglichkeit, das zu tun ...
Schnittstellen, die Klassen erweitern
Wenn ein Schnittstellentyp einen Klassentyp erweitert, erbt er die Mitglieder der Klasse, jedoch nicht deren Implementierungen. Es ist, als hätte die Schnittstelle alle Mitglieder der Klasse deklariert, ohne eine Implementierung bereitzustellen. Schnittstellen erben sogar die privaten und geschützten Mitglieder einer Basisklasse. Dies bedeutet, dass beim Erstellen einer Schnittstelle, die eine Klasse mit privaten oder geschützten Mitgliedern erweitert, dieser Schnittstellentyp nur von dieser Klasse oder einer Unterklasse davon implementiert werden kann.
Dies ist nützlich, wenn Sie eine große Vererbungshierarchie haben, aber angeben möchten, dass Ihr Code nur mit Unterklassen mit bestimmten Eigenschaften funktioniert. Die Unterklassen müssen nicht miteinander verknüpft sein, außer von der Basisklasse zu erben. Beispielsweise:
class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control implements SelectableControl { select() { } } class TextBox extends Control { select() { } } // Error: Property 'state' is missing in type 'Image'. class Image implements SelectableControl { private state: any; select() { } } class Location { }
Also, während
extends
bedeutet - es bekommt alles von seinem Elternteilimplements
In diesem Fall ist es fast so, als würde man eine Schnittstelle implementieren. Untergeordnetes Objekt kann so tun, als wäre es übergeordnet ... aber es wird nicht implementiertextends
-es bekommt alles von seinem Elternteil", gilt es für private Mitglieder? Zum Beispiel class Person {private name: string} class man extends Person{gender: string;}
hat man
die Eigenschaft Namen?
In Typoskript (und einigen anderen OO-Sprachen) haben Sie Klassen und Schnittstellen.
Eine Schnittstelle hat keine Implementierung, es ist nur ein "Vertrag" darüber, welche Mitglieder / Methoden dieser Typ hat.
Beispielsweise:
interface Point {
x: number;
y: number;
distance(other: Point): number;
}
Instanzen, die diese Point
Schnittstelle implementieren , müssen zwei Mitglieder vom Typ number: x
und y
und eine Methode haben, distance
die eine andere Point
Instanz empfängt und a zurückgibt number
.
Die Schnittstelle implementiert keine davon.
Klassen sind die Implementierungen:
class PointImplementation implements Point {
public x: number;
public y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
public distance(other: Point): number {
return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
}
}
In Ihrem Beispiel behandeln Sie Ihre Person
Klasse einmal als Klasse, wenn Sie sie erweitern, und einmal als Schnittstelle, wenn Sie sie implementieren.
Dein Code:
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
Hat einen Kompilierungsfehler, der sagt:
Die Klasse 'Man' implementiert die Schnittstelle 'Person' falsch.
Die Eigenschaft 'name' fehlt im Typ 'Man'.
Und das liegt daran, dass Schnittstellen nicht implementiert sind.
Wenn Sie also implement
eine Klasse sind, nehmen Sie nur ihren "Vertrag" ohne die Implementierung, also müssen Sie dies tun:
class NoErrorMan implements Person {
name: string;
age: number;
}
Fazit ist, dass Sie in den meisten Fällen zu einer extend
anderen Klasse und nicht zu implement
dieser wollen.
Tolle Antwort von @ nitzan-tomer! Hat mir sehr geholfen ... Ich habe seine Demo ein wenig erweitert mit:
IPoint interface;
Point implements IPoint;
Point3D extends Point;
Und wie sie sich in Funktionen verhalten, die einen IPoint
Typ erwarten .
Was ich bisher gelernt und als Faustregel verwendet habe: Wenn Sie Klassen und Methoden verwenden, die generische Typen erwarten, verwenden Sie Schnittstellen als erwartete Typen. Stellen Sie sicher, dass das übergeordnete Element oder die Basisklasse diese Schnittstelle verwendet. Auf diese Weise können Sie alle Unterklassen in diesen verwenden, sofern sie die Schnittstelle implementieren.
Hier die erweiterte Demo
extends
Konzentrieren Sie sich auf das Erben und implements
auf Einschränkungen, ob Schnittstellen oder Klassen.
extends
: Die untergeordnete Klasse (die erweitert wird) erbt alle Eigenschaften und Methoden der erweiterten Klasseimplements
: Die Klasse, die das implements
Schlüsselwort verwendet, muss alle Eigenschaften und Methoden der Klasse implementieren, die sie verwendetimplements
Einfacher ausgedrückt:
extends
: Hier erhalten Sie alle diese Methoden / Eigenschaften von der übergeordneten Klasse, sodass Sie dies nicht selbst implementieren müssenimplements
: Hier ist ein Vertrag, dem die Klasse folgen muss. Die Klasse muss mindestens die folgenden Methoden / Eigenschaften implementierenclass Person {
name: string;
age: number;
walk(): void {
console.log('Walking (person Class)')
}
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class child extends Person { }
// Man has to implements at least all the properties
// and methods of the Person class
class man implements Person {
name: string;
age: number
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
walk(): void {
console.log('Walking (man class)')
}
}
(new child('Mike', 12)).walk();
// logs: Walking(person Class)
(new man('Tom', 12)).walk();
// logs: Walking(man class)
Im Beispiel können wir beobachten, dass die untergeordnete Klasse alles von Person erbt, während die man-Klasse alles von Person selbst implementieren muss.
Wenn wir etwas aus der man-Klasse entfernen würden, zum Beispiel die walk-Methode, würden wir den folgenden Kompilierungszeitfehler erhalten :
Die Klasse 'man' implementiert die Klasse 'Person' falsch. Wollten Sie 'Person' erweitern und seine Mitglieder als Unterklasse erben? Die Eigenschaft 'walk' fehlt im Typ 'man', ist jedoch im Typ 'Person' erforderlich. (2720)