przeciążanie metoda?

głosy
75

Czy istnieje sposób, aby zrobić metoda przeciążenia w języku maszynopis?

Chcę osiągnąć coś takiego:

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);

Oto przykład tego, czego nie chcą robić (Nienawidzę tej części przeciążenia siekać w 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);
Utwórz 02/10/2012 o 11:03
źródło użytkownik
W innych językach...                            


6 odpowiedzi

głosy
107

Zgodnie ze specyfikacją, maszynopis robi metoda wsparcie przeciążenia, ale jest to dość niewygodne i zawiera dużo pracy ręcznej kontroli typów parametrów. Myślę, że to głównie dlatego, że najbliżej można dostać się do metody przeciążenia w czystym JavaScript obejmuje sprawdzenie, że zbyt maszynopis i stara się nie modyfikować rzeczywistych ciał metoda, aby uniknąć niepotrzebnych kosztów wydajność środowiska wykonawczego.

Jeśli rozumiem go poprawnie, trzeba najpierw napisać deklarację metody dla każdego z przeciążeniami, a następnie jeden realizację metoda, która sprawdza swoje argumenty aby zdecydować, które nazwano przeciążeniowe. Podpis wykonania musi być zgodny ze wszystkimi przeciążeniami.

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);
    }
}
Odpowiedział 02/10/2012 o 12:00
źródło użytkownik

głosy
18

Aktualizacja dla jasności. Metoda przeciążenia w maszynopisie Jest to przydatna funkcja, o ile pozwala na tworzenie definicji typu istniejących bibliotek z API, które muszą być reprezentowane.

Podczas pisania własnego kodu, chociaż, może również być w stanie uniknąć przeciążenia poznawczego napowietrznej Korzystanie z opcjonalnych lub domyślne parametry. Jest to tym bardziej czytelna alternatywa dla metody przeciążeń, a także utrzymuje API uczciwy jak będziesz unikać tworzenia przeciążeń z nieintuicyjne zamawiania.

Ogólne prawo maszynopis przeciąża to:

Jeśli możesz usuwać podpisy przeciążeniem i wszystkich testów przechodzą, nie trzeba przeciążeń maszynopis

Zazwyczaj można osiągnąć to samo z opcjonalnych lub domyślnych parametrów - lub z typów związków, lub z odrobiną orientacji obiektu.

Rzeczywiste pytanie

Rzeczywiste pytanie prosi o przeciążeniu:

someMethod(stringParameter: string): void {

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

Teraz nawet w językach, które obsługują przeciążeń z oddzielnymi wdrożeń (uwaga: maszynopis przeciążenia udostępnić pojedynczy Wykonanie) - programiści są porady w celu zapewnienia spójności w zamówieniu. Pozwoliłoby podpisy:

someMethod(stringParameter: string): void {

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

stringParameterZawsze jest wymagane, więc to idzie pierwszy. Można napisać to jako przeciążenie maszynopis pracy:

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

Ale po prawie przeciążeń maszynopis, możemy usuwać podpisy przeciążeniem i wszystkie nasze testy będą nadal przechodzić.

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

Rzeczywiste pytanie, w rzeczywistej Zakonu

Jeśli zostały określone utrzymują się z oryginalnym porządku, przeciążenia byłoby:

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;
    }
  }
}

Teraz to o wiele rozgałęzień wypracować gdzie umieścić parametry, ale naprawdę chciał zachować ten porządek, jeśli czytasz ten daleko ... ale zaraz, co się dzieje, jeśli zastosujemy prawo przeciążeń maszynopis?

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;
    }
  }
}

Już wystarczająco Rozgałęzienia

Oczywiście, biorąc pod uwagę ilość typ kontroli musimy zrobić ... może najlepszą odpowiedzią jest po prostu mieć dwie metody:

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

someOtherMethod(numberParameter: number, stringParameter: string): void {
  //...
}
Odpowiedział 02/10/2012 o 11:16
źródło użytkownik

głosy
7

Chciałbym. Chcę tej funkcji zbyt ale maszynopis musi być interoperacyjne z bez typu JavaScript, który nie ma przeciążone metody. tj Jeśli przeciążona metoda jest wywoływana z JavaScript to może dostać wysyłane tylko do jednej z implementacji metody.

Istnieje kilka istotnych \ sa dyskusje na CodePlex. na przykład

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

Nadal uważam, że maszynopis powinien generować wszystkie if'ing i przełączanie więc nie trzeba robić.

Odpowiedział 20/07/2013 o 15:11
źródło użytkownik

głosy
2

Javascript nie ma żadnego pojęcia przeciążenia. Maszynopis nie jest C # lub Java.

Ale można wdrożyć przeciążenia w maszynopisie.

Przeczytaj ten artykuł http://www.gyanparkash.in/function-overloading-in-typescript/

Odpowiedział 08/12/2018 o 06:15
źródło użytkownik

głosy
1

Dlaczego nie używać opcjonalnej właściwości zdefiniowany interfejs jako argument funkcji ..

W przypadku, w tej kwestii, z wykorzystaniem interfejsu inline zdefiniowany z niektórych opcjonalnych właściwościach tylko mógł bezpośrednio wprowadzać kod jak coś poniżej:

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" });

Ponieważ w maszynopisie przeciążeń warunkiem jest, jak wspomniano w komentarzach innych, tylko liście różnych podpisów funkcja bez wsparcia odpowiednich kodów wykonawczych jak innych językach statycznych. Zatem realizacja nadal muszą być wykonane tylko w jednym ciele funkcji, co sprawia, że ​​korzystanie z funkcji przeciążenia w maszynopisie nie tak wygodne jak tych językach wspierających funkcję przeciążenia rzeczywistym.

Jednak nadal istnieje wiele nowych i wygodnych Produkty znajdujące się w maszynie, która nie jest dostępna w języku programowania Legacy, gdzie opcjonalne wsparcie nieruchomość w anonimowej interfejs jest takie podejście, aby sprostać komfortową strefę z przeciążenia funkcji starszego typu, myślę.

Odpowiedział 10/12/2017 o 15:12
źródło użytkownik

głosy
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;
    }
  }

}

Myślę, że to powinno działać

Odpowiedział 28/06/2017 o 05:50
źródło użytkownik

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