Перегрузка методов?

голоса
75

Есть ли способ сделать перегрузку методов в языке машинописи?

Я хочу, чтобы достичь чего-то вроде этого:

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

Вот пример того, что я не хочу делать (я действительно ненавижу эту часть перегрузки хака в 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);
Задан 02/10/2012 в 11:03
источник пользователем
На других языках...                            


6 ответов

голоса
107

Согласно спецификации, машинопись делает метод поддержки перегрузки, но это довольно неудобно, и включает в себя много ручной работы, проверка типов параметров. Я думаю, что это в основном потому, что ближайшее вы можете получить метод перегрузки в простом JavaScript включает в себя проверку, что также и машинопись пытается не изменять фактические тела методов, чтобы избежать ненужных затрат производительности во время выполнения.

Если я правильно понимаю, вы должны сначала написать заявление метода для каждого из перегрузок , а затем один реализацию методы , который проверяет аргументы решить , какие перегрузки называются. Сигнатура реализации должен быть совместим со всеми перегрузками.

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);
    }
}
Ответил 02/10/2012 в 12:00
источник пользователем

голоса
18

Обновление для ясности. Метод перегрузки в машинописном полезная функция, поскольку она позволяет создавать определения типов существующих библиотек с API, который должен быть представлен.

При написании собственного кода, хотя, вы вполне можете быть в состоянии избежать когнитивного накладные расходов перегрузок с использованием дополнительных или по умолчанию параметров. Это более читаемой альтернатива методы перегрузок, а также держит ваш API честны, как вы будете избегать создания перегрузок с неинтуитивной упорядоченностью.

Общий закон машинопись перегружает является:

Если вы можете удалить подписи перегрузки и все тесты проходят, вам не нужно машинопись перегрузкам

Обычно вы можете достичь того же с дополнительными, или по умолчанию параметры - или с типами профсоюзов, или с небольшим количеством объектно-ориентированного программирования.

Фактический вопрос

Фактический вопрос задает для перегрузки:

someMethod(stringParameter: string): void {

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

Теперь даже в языках, которые поддерживают перегруженные с отдельными реализациями (примечание: машинопись перегрузки разделяют единую реализацию) - программисты советы, чтобы обеспечить последовательность в упорядочении. Это сделало бы подписи:

someMethod(stringParameter: string): void {

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

stringParameterВсегда требуется, поэтому он идет первым. Вы могли бы написать это как перегрузка рабочей Машинописи:

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

Но после закона машинописи перегрузок, мы можем удалить подписи перегрузки, и все наши тесты еще пройти.

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

Фактический вопрос, в фактическом порядке

Если вы решили оставаться с оригинальным порядке, перегруженные бы:

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

Теперь, когда много разветвлений, чтобы решить, где поставить параметры, но вы действительно хотите сохранить этот порядок, если вы читаете это далеки ... но ждать, что произойдет, если мы применим закон машинопись перегрузок?

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

Достаточно Ветвление Уже

Конечно, учитывая количество проверки типа мы должны сделать ... Может быть, лучший ответ просто есть два метода:

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

someOtherMethod(numberParameter: number, stringParameter: string): void {
  //...
}
Ответил 02/10/2012 в 11:16
источник пользователем

голоса
7

Я хочу. Я хочу эту функцию, но слишком машинопись должна быть совместим с нетипизированным JavaScript, который не имеет перегруженные методы. то есть, если ваш перегруженный метод вызывается из JavaScript, то он только может получить отправлен в одном из вариантов осуществления способа.

Там \ са несколько соответствующих обсуждений на CodePlex. например

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

Я до сих пор думаю, что машинопись должна генерировать все if'ing и переключение таким образом, мы не должны были бы сделать это.

Ответил 20/07/2013 в 15:11
источник пользователем

голоса
2

Javascript не имеет никакого понятия о перегрузке. Машинопись не C # или Java.

Но вы можете реализовать перегрузку в машинописи.

Прочитайте этот пост http://www.gyanparkash.in/function-overloading-in-typescript/

Ответил 08/12/2018 в 06:15
источник пользователем

голоса
1

Почему бы не использовать определенный интерфейс необязательного свойства в качестве аргумента функции ..

Для случая, в этом вопросе, используя встроенный интерфейс, определенный с некоторыми дополнительными свойствами только может непосредственно сделать код как-то ниже:

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

Поскольку перегрузка обеспечивается в машинописном, как уже упоминались в комментариях других людей, просто список различных сигнатуры функций в без поддержки соответствующих кодов реализации, как и других статических языки. Таким образом, реализация все еще должна быть сделана только одна функцией тела, что делает использование функции перегрузки в машинописном не максимально комфортных таких языках, поддерживающих реальную возможность перегрузки.

Тем не менее, есть еще много нового и удобное питания, предоставляемого в машинописи, который не доступен на языке программирования наследия, где опциональная поддержка недвижимости в анонимном интерфейсе является таким подход, чтобы удовлетворить комфортную зону от унаследованной функции перегрузки, я думаю.

Ответил 10/12/2017 в 15:12
источник пользователем

голоса
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;
    }
  }

}

Я думаю, что это должно работать

Ответил 28/06/2017 в 05:50
источник пользователем

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