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.

21
demandé sur Daniel Hitzel 2016-03-15 00:41:08

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.

15
répondu Aaron 2016-03-14 21:51:50

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
20
répondu basarat 2016-03-14 23:39:18

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);
    }
  }
}
0
répondu PeeWee2201 2018-05-03 13:12:18

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)
    }
}
-2
répondu Rodolfo Patane 2017-04-23 21:11:50