Metodo sovraccarico?

voti
75

C'è un modo per fare overloading dei metodi nel linguaggio tipografico?

Voglio ottenere qualcosa di simile a questo:

class TestClass {
    someMethod(stringParameter: string): void {
        alert(Variant #1: stringParameter =  + stringParameter);
    }

    someMethod(numberParameter: number, stringParameter: string): void {
        alert(Variant #2: numberParameter =  + numberParameter + , stringParameter =  + stringParameter);
    }
}

var testClass = new TestClass();
testClass.someMethod(string for v#1);
testClass.someMethod(12345, string for v#2);

Ecco un esempio di quello che non voglio fare (Io odio che una parte del sovraccarico mod in JS):

class TestClass {
    private someMethod_Overload_string(stringParameter: string): void {
        // A lot of code could be here... I don't want to mix it with switch or if statement in general function
        alert(Variant #1: stringParameter =  + stringParameter);
    }

    private someMethod_Overload_number_string(numberParameter: number, stringParameter: string): void {
        alert(Variant #2: numberParameter =  + numberParameter + , stringParameter =  + stringParameter);
    }

    private someMethod_Overload_string_number(stringParameter: string, numberParameter: number): void {
        alert(Variant #3: stringParameter =  + stringParameter + , numberParameter =  + numberParameter);
    }

    public someMethod(stringParameter: string): void;
    public someMethod(numberParameter: number, stringParameter: string): void;
    public someMethod(stringParameter: string, numberParameter: number): void;

    public someMethod(): void {
        switch (arguments.length) {
        case 1:
            if(typeof arguments[0] == string) {
                this.someMethod_Overload_string(arguments[0]);
                return;
            }
            return; // Unreachable area for this case, unnecessary return statement
        case 2:
            if ((typeof arguments[0] == number) &&
                (typeof arguments[1] == string)) {
                this.someMethod_Overload_number_string(arguments[0], arguments[1]);
            }
            else if ((typeof arguments[0] == string) &&
                     (typeof arguments[1] == number)) {
                this.someMethod_Overload_string_number(arguments[0], arguments[1]);
            }
            return; // Unreachable area for this case, unnecessary return statement
        }
    }
}


var testClass = new TestClass();
testClass.someMethod(string for v#1);
testClass.someMethod(12345, string for v#2);
testClass.someMethod(string for v#3, 54321);
È pubblicato 02/10/2012 alle 11:03
fonte dall'utente
In altre lingue...                            


6 risposte

voti
107

Secondo le specifiche, dattiloscritto fa metodo supportano l'overload, ma è abbastanza scomodo e comprende un sacco di lavoro manuale controllo tipi di parametri. Penso che sia soprattutto perché il più vicino si può arrivare a overloading dei metodi in pianura JavaScript comprende che il controllo troppo e dattiloscritto cerca di non modificare i corpi metodo effettivo per evitare qualsiasi costo delle prestazioni di runtime non necessaria.

Se ho capito bene, si deve scrivere prima una dichiarazione di metodo per ciascuno dei sovraccarichi e quindi un'implementazione del metodo che controlla i suoi argomenti per decidere quale di sovraccarico è stato chiamato. La firma di attuazione deve essere compatibile con tutti i sovraccarichi.

class TestClass {
    someMethod(stringParameter: string): void;
    someMethod(numberParameter: number, stringParameter: string): void;

    someMethod(stringOrNumberParameter: any, stringParameter?: string): void {
        if (stringOrNumberParameter && typeof stringOrNumberParameter == "number")
            alert("Variant #2: numberParameter = " + stringOrNumberParameter + ", stringParameter = " + stringParameter);
        else
            alert("Variant #1: stringParameter = " + stringOrNumberParameter);
    }
}
Risposto il 02/10/2012 a 12:00
fonte dall'utente

voti
18

Aggiornamento per chiarezza. Metodo sovraccarico a macchina è una caratteristica utile in quanto permette di creare definizioni del tipo per le biblioteche esistenti con un'API che ha bisogno di essere rappresentati.

Quando si scrive il proprio codice, però, si può ben essere in grado di evitare il sovraccarico cognitivo dei sovraccarichi che utilizzano parametri opzionali o di default. Questo è il più leggibile alternativa al metodo sovraccarichi e mantiene anche la vostra API onesto come si evitano la creazione di sovraccarichi con ordine poco intuitivo.

La legge generale della dattiloscritto sovraccarica è:

Se è possibile eliminare le firme di sovraccarico e di tutti i test passano, non è necessario sovraccarichi dattiloscritto

Di solito è possibile ottenere la stessa cosa con i parametri facoltativi, o di default - o con i tipi di unione, o con un po 'di orientamento agli oggetti.

La questione reale

La domanda attuale richiede un sovraccarico di:

someMethod(stringParameter: string): void {

someMethod(numberParameter: number, stringParameter: string): void {

Ora anche nelle lingue che sostengono sovraccarichi con implementazioni distinte (nota: sovraccarichi dattiloscritto condividono una singola implementazione) - programmatori sono consigli per fornire coerenza nella ordinazione. Questo renderebbe le firme:

someMethod(stringParameter: string): void {

someMethod(stringParameter: string, numberParameter: number): void {

Il stringParameterè sempre necessario, così si va per primo. Si potrebbe scrivere questo come un sovraccarico di lavoro dattiloscritto:

someMethod(stringParameter: string): void;
someMethod(stringParameter: string, numberParameter: number): void;
someMethod(stringParameter: string, numberParameter?: number): void {
    if (numberParameter != null) {
        // The number parameter is present...
    }
}

Ma dopo la legge di sovraccarichi dattiloscritto, siamo in grado di eliminare le firme di sovraccarico e di tutti i nostri test sarà ancora passare.

someMethod(stringParameter: string, numberParameter?: number): void {
    if (numberParameter != null) {
        // The number parameter is present...
    }
}

La questione reale, nell'ordine effettivo

Se si erano decisi a persistere con l'ordine originale, i sovraccarichi sarebbero:

someMethod(stringParameter: string): void;
someMethod(numberParameter: number, stringParameter: string): void;
someMethod(a: string | number, b?: string | number): void {
  let stringParameter: string;
  let numberParameter: number;

  if (typeof a === 'string') {
    stringParameter = a;
  } else {
    numberParameter = a;

    if (typeof b === 'string') {
      stringParameter = b;
    }
  }
}

Ora che è un sacco di ramificazione per capire dove mettere i parametri, ma si ha realmente voluto conservare questo ordine se state leggendo questo lontano ... ma aspetta, cosa succede se applichiamo la legge di sovraccarichi dattiloscritto?

someMethod(a: string | number, b?: string | number): void {
  let stringParameter: string;
  let numberParameter: number;

  if (typeof a === 'string') {
    stringParameter = a;
  } else {
    numberParameter = a;

    if (typeof b === 'string') {
      stringParameter = b;
    }
  }
}

Basta Branching Già

Naturalmente, data la quantità di controllo di tipo abbiamo bisogno di fare ... forse la risposta migliore è semplicemente quello di avere due metodi:

someMethod(stringParameter: string): void {
  this.someOtherMethod(0, stringParameter);
}

someOtherMethod(numberParameter: number, stringParameter: string): void {
  //...
}
Risposto il 02/10/2012 a 11:16
fonte dall'utente

voti
7

Spero. Voglio che questa caratteristica troppo ma dattiloscritto deve essere interoperabile con JavaScript senza tipo che non ha metodi di overload. cioè se il vostro metodo di overload viene chiamato da JavaScript, allora si può ottenere spedito solo a un'implementazione del metodo.

Ci \ Sa alcune discussioni importanti su CodePlex. per esempio

https://typescript.codeplex.com/workitem/617

Penso ancora che dattiloscritto dovrebbe generare tutto l'if'ing e commutazione in modo che non avrebbe bisogno di farlo.

Risposto il 20/07/2013 a 15:11
fonte dall'utente

voti
2

Javascript non ha alcun concetto di sovraccarico. Dattiloscritto non è C # o Java.

Ma è possibile implementare un sovraccarico a macchina.

Leggi questo post http://www.gyanparkash.in/function-overloading-in-typescript/

Risposto il 08/12/2018 a 06:15
fonte dall'utente

voti
1

Perché non utilizzare l'interfaccia definita proprietà facoltativa come l'argomento della funzione ..

Per il caso in questione, utilizzando un'interfaccia in linea definita con alcune proprietà opzionali solo potrebbe rendere il codice direttamente come qualcosa di seguito:

class TestClass {

    someMethod(arg: { stringParameter: string, numberParameter?: number }): void {
        let numberParameterMsg = "Variant #1:";
        if (arg.numberParameter) {
            numberParameterMsg = `Variant #2: numberParameter = ${arg.numberParameter},`;
        }
        alert(`${numberParameterMsg} stringParameter = ${arg.stringParameter}`);
    }
}

var testClass = new TestClass();
testClass.someMethod({ stringParameter: "string for v#1" });
testClass.someMethod({ numberParameter: 12345, stringParameter: "string for v#2" });

Poiché sovraccarichi fornito a macchina è, come detto in commenti degli altri, solo un elenco di firme diverse della funzione senza sostenere codici di attuazione corrispondenti come altri linguaggi statici. Così l'attuazione devono ancora essere fatto in un solo corpo della funzione, il che rende l'uso della funzione di sovraccarico a macchina non confortevoli come tali linguaggi che supportano la funzione di sovraccarico reale.

Tuttavia, c'è ancora molte materie nuove e convenienti fornite a macchina che non è disponibile nel linguaggio di programmazione legacy, in cui il sostegno proprietà facoltativa in un'interfaccia anonimo è un tale approccio per soddisfare la zona confortevole dalla funzione legacy sovraccarico, credo.

Risposto il 10/12/2017 a 15:12
fonte dall'utente

voti
0
class User{
   name : string;
   age : number;
   constructor(name:string,age:number){
    this.name = name;
    this.age = age;
    console.log("User " +this.name+ " Created")
}
getName(name:string = ""):string{
    if(name != ""){
        return name + " " +this.name;
    }else{
        return this.name;
    }
  }

}

Penso che questo dovrebbe funzionare

Risposto il 28/06/2017 a 05:50
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more