J'aimerais savoir ce que l' homme et l' enfant ont en commun et en quoi ils diffèrent.
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
J'aimerais savoir ce que l' homme et l' enfant ont en commun et en quoi ils diffèrent.
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
Réponses:
extends
veux dire:La nouvelle classe est un enfant . Il tire des avantages de l'héritage. Il a toutes les propriétés, méthodes comme parent. Il peut remplacer certains d'entre eux et en implémenter de nouveaux, mais les éléments parents sont déjà inclus.
implements
veux dire:La nouvelle classe peut être traitée comme la même "forme" , alors qu'elle n'est pas un enfant . Il peut être passé à n'importe quelle méthode où le Person
est requis, indépendamment du fait d'avoir un parent différent dePerson
En POO (langages comme C #, Java), nous utiliserions
extends
pour profiter de l'héritage (voir wiki ). Petite cite:
... L'héritage dans la plupart des langages orientés objet basés sur des classes est un mécanisme dans lequel un objet acquiert toutes les propriétés et tous les comportements de l'objet parent. L'héritage permet aux programmeurs de: créer des classes basées sur des classes existantes ...
implements
sera plus pour le polymorphisme (voir wiki ). Petite cite:
... le polymorphisme est la fourniture d'une interface unique à des entités de types différents ...
Ainsi, nous pouvons avoir un arbre d'héritage vraiment différent de notre class Man
.
class Man extends Human ...
mais si nous déclarons également que nous pouvons prétendre être d'un type différent - Person
:
class Man extends Human
implements Person ...
.. alors nous pouvons l'utiliser n'importe où, là où cela Person
est nécessaire. Nous devons juste remplir les conditions des personnes "interface"
(c'est-à-dire mettre en œuvre toutes ses activités publiques) .
implement
autre classe? C'est vraiment coolLe joli visage de Javascript (l'un des avantages) est le support intégré de la saisie Duck ( voir wiki ). Petite cite:
"Si ça marche comme un canard et ça caque comme un canard, alors ce doit être un canard."
Donc, en Javascript, si deux objets différents ... auraient une méthode similaire (par exemple render()
) ils peuvent être passés à une fonction qui l'attend:
function(engine){
engine.render() // any type implementing render() can be passed
}
Pour ne pas perdre cela - nous pouvons faire de même dans Typescript - avec un support plus typé. Et c'est là que
class implements class
a son rôle, là où ça a du sens
Dans les langues POO comme C#
... pas moyen de faire ça ...
Interfaces étendant les classes
Lorsqu'un type d'interface étend un type de classe, il hérite des membres de la classe mais pas de leurs implémentations. C'est comme si l'interface avait déclaré tous les membres de la classe sans fournir d'implémentation. Les interfaces héritent même des membres privés et protégés d'une classe de base. Cela signifie que lorsque vous créez une interface qui étend une classe avec des membres privés ou protégés, ce type d'interface ne peut être implémenté que par cette classe ou une sous-classe de celle-ci.
Cela est utile lorsque vous avez une grande hiérarchie d'héritage, mais que vous souhaitez spécifier que votre code fonctionne uniquement avec les sous-classes qui ont certaines propriétés. Les sous-classes n'ont pas besoin d'être liées en plus d'hériter de la classe de base. Par exemple:
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 { }
Donc pendant
extends
signifie - il obtient tout de son parentimplements
dans ce cas, c'est presque comme implémenter une interface. L'objet enfant peut prétendre qu'il est parent ... mais il n'obtient aucune implémentationextends
-il obtient tout de son parent", cela s'applique-t-il aux membres privés? Par exemple n'avoir le nom de la propriété? class Person {private name: string} class man extends Person{gender: string;}
man
En typographie (et dans certains autres langages OO), vous avez des classes et des interfaces.
Une interface n'a pas d'implémentation, c'est juste un "contrat" des membres / méthodes de ce type.
Par exemple:
interface Point {
x: number;
y: number;
distance(other: Point): number;
}
Les instances qui implémentent cette Point
interface doivent avoir deux membres de type number: x
and y
, et une méthode distance
qui reçoit une autre Point
instance et renvoie un number
.
L'interface n'implémente aucun de ceux-ci.
Les classes sont les implémentations:
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));
}
}
( code dans la cour de récréation )
Dans votre exemple, vous traitez votre Person
classe une fois comme une classe lorsque vous l'étendez et une fois comme une interface lorsque vous l'implémentez.
Votre code:
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
A une erreur de compilation disant:
La classe 'Man' implémente incorrectement l'interface 'Person'.
La propriété «nom» est manquante dans le type «Homme».
Et c'est parce que les interfaces manquent d'implémentation.
Donc, si vous avez implement
une classe, vous ne prenez que son "contrat" sans l'implémentation, vous devrez donc faire ceci:
class NoErrorMan implements Person {
name: string;
age: number;
}
( code dans la cour de récréation )
En fin de compte, dans la plupart des cas, vous voulez une extend
autre classe et non pas à implement
elle.
Excellente réponse de @ nitzan-tomer! M'a beaucoup aidé ... J'ai prolongé un peu sa démo avec:
IPoint interface;
Point implements IPoint;
Point3D extends Point;
Et comment ils se comportent dans les fonctions qui attendent un IPoint
type.
Donc, ce que j'ai appris jusqu'à présent et que j'ai utilisé comme règle empirique: si vous utilisez des classes et des méthodes qui attendent des types génériques, utilisez des interfaces comme types attendus. Et assurez-vous que le parent ou la classe de base utilise cette interface. De cette façon, vous pouvez utiliser toutes les sous-classes de celles-ci dans la mesure où elles implémentent l'interface.
Voici la démo étendue
extends
se concentrer sur l'héritage et se implements
concentrer sur la contrainte, qu'il s'agisse d'interfaces ou de classes.
extends
: La classe enfant (qui est étendue) héritera de toutes les propriétés et méthodes de la classe est étendimplements
: La classe qui utilise le implements
mot - clé devra implémenter toutes les propriétés et méthodes de la classe qu'elleimplements
En termes plus simples:
extends
: Ici, vous obtenez toutes ces méthodes / propriétés de la classe parente, vous n'avez donc pas à l'implémenter vous-mêmeimplements
: Voici un contrat que la classe doit suivre. La classe doit implémenter au moins les méthodes / propriétés suivantesclass 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)
Dans l'exemple, nous pouvons observer que la classe enfant hérite de tout de Person alors que la classe man doit tout implémenter de Person elle-même.
Si nous supprimions quelque chose de la classe man, par exemple la méthode de marche, nous obtiendrions l' erreur de compilation suivante :
La classe 'man' implémente incorrectement la classe 'Person'. Vouliez-vous étendre «Personne» et hériter de ses membres en tant que sous-classe? La propriété 'walk' est manquante dans le type 'man' mais obligatoire dans le type 'Person'. (2720)