Surcharge du constructeur avec le constructeur vide
Pourquoi est-il interdit d'avoir séparé constructor
définitions dactylographié<!--12?
Pour avoir par exemple deux constructors
, j'ai besoin d'écrire mon code comme ceci.
constructor(id: number)
constructor(id: number, name?: string, surname?: string, email?: string) {
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
}
ainsi je dois mettre ?
après les choses que je veux être pas nécessaire.
Pourquoi Je ne peux pas l'écrire comme ça?
constructor(id: number) {
this.id = id;
}
constructor(id: number, name: string, surname: string, email: string) {
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
}
de Sorte que, pour chaque constructeur, tous les paramètres sont obligatoires.
De Plus I besoin d'avoir un constructeur vide. Cela devient encore plus étrange, puisque je dois marquer chaque paramètre avec un ?
.
constructor()
constructor(id?: number, name?: string, surname?: string, email?: string) {
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
}
Pourquoi dactylographié diffère des langues courantes comme C#
ou Python
ici?
je m'attends à ce que cela fonctionne comme cela.
constructor() {
}
constructor(id: number, name: string, surname: string, email: string) {
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
}
vous pouvez passer aucun paramètre ou devez passer les paramètres.
4 réponses
parce que votre implémentation de constructeur est appelée par tous vos constructeurs de surcharge. (Techniquement, à l'exécution il n'y a qu'une seule fonction de constructeur qui est appelée avec les différentes signatures d'arguments de surcharge.)
Imagine comme ça:
overload_constructor(id:string) {
implementation_constructor(id);
}
implementation_constructor(id:string, name?:string, age?:number) {
// ...
}
Penser à elle de cette façon, overload_constructor
ne implementation_constructor
à moins que name
et age
sont en option.
la dernière surcharge de fonction n'est utilisée que dans la mise en oeuvre et n'est pas disponible publiquement. Ceci est illustré ci-dessous:
class Foo{
constructor()
constructor(id?: number) {
}
}
const foo1 = new Foo();
const foo2 = new Foo(123); // Error! : not public
Si vous voulez id:number
pour être disponibles publiquement, bien sûr, vous pouvez ajouter une autre surcharge:
class Foo{
constructor()
constructor(id: number)
constructor(id?: number) {
}
}
const foo1 = new Foo();
const foo2 = new Foo(123); // Okay
const foo3 = new Foo('hello'); // Error: Does not match any public overload
La raison en est que la Machine tente de ne pas faire de fantaisie de génération de code pour la fonction de surcharge (langues traditionnelles de faire cela en utilisant le nom d'amputation par exemple, C++)
ainsi vous pouvez passer aucun paramètre ou doit passer paramètre.
en fait, vous pouvez rendre la surcharge finale optionnelle, mais aucune des surcharge publiques n'est optionnelle. Considérons l'exemple suivant:
class Foo{
constructor(id: number, name:string)
constructor(name:string)
constructor(idOrName?: number|string, name?:string) {
}
}
const foo1 = new Foo('name'); // Okay
const foo2 = new Foo(123); // Error: you must provide a name if you use the id overload
const foo3 = new Foo(123,'name'); // Okay
Vous pouvez utiliser Builder pattern pour résoudre ce problème. Même en C# ou Python, cela devient rapidement une meilleure approche au fur et à mesure que le nombre d'arguments du constructeur augmente.
class Foo {
constructor(public id: number, public name: string, public surname: string, public email: string) {
}
static Builder = class {
id: number = NaN;
name: string = null;
surname: string = null;
email: string = null;
Builder() {
}
build(): Foo {
return new Foo(this.id, this.name, this.surname, this.email);
}
}
}
si vous utilisez des méthodes statiques pour mettre en œuvre des contructeurs de surcharge, voir.
export class User implements IUser {
constructor(
private _id: string,
private _name: string,
private _email: string,
) {}
static New(jsonUser:string){
return new User(
JSON.parse(jsonUser).id,
JSON.parse(jsonUser).name,
JSON.parse(jsonUser).email)
}
}