Создать экземпляр класса с абстрактным методом - PullRequest
0 голосов
/ 06 сентября 2018

С помощью Java мы можем создать экземпляр класса ActionListener, который имеет абстрактный метод, что-то вроде этого (это было некоторое время):

new ActionListener(){
  @Override
  public void actionPerformed(ActionEvent e) {
     // whatever
  }
}

с использованием TypeScript, это самый близкий к нему доступэто:

export abstract class ActionListener {

  constructor(f: any) {
    this.actionPerformed = f;
  }

  abstract actionPerformed(input: string): string;

}


new ActionListener(input => {

});

есть как минимум 2 проблемы:

  1. Если вы используете абстрактный метод с TS, класс должен абстрагироваться (я думаю, с Java выможет иметь абстрактные методы, которые могут быть реализованы позже).

  2. Я не знаю, как связать / привязать тип входной функции f к типу метода разбора.

Кто-нибудь знает, есть ли способ сделать это с TS?

Возможно, мы не можем использовать abstract с TS, и нам придется делать это больше какэто:

type ActionPerformed = (input: string) => string;

export class ActionListener {

  parse: ActionPerformed;

  constructor(f: ActionPerformed) {
    this.parse = f;
  }

}

new ActionListener(input => {
  return 'foo';
});

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Это не требуется в JavaScript или TypeScript. В Java нет понятия функций как объектов первого класса, лямбды - просто сахар для экземпляров объектов, которые реализуют функциональный интерфейс.

Таким образом, идиоматический способ в JS / TS состоит в том, чтобы не иметь здесь класс, а просто передать функцию обратного вызова:

interface ActionListener {
  (ev: Event) => void;
}

function iNeedAnActionHandler(actionListener: ActionListener) {
  // do stuff
  const ev = new Event(); // whatever
  actionListener(ev);
}

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

0 голосов
/ 06 сентября 2018

С помощью Java мы можем создать экземпляр класса ActionListener, у которого есть абстрактный метод

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

То, что вы можете сделать, это вы можете создать подкласс этого абстрактного класса, который реализует этот абстрактный метод, и вы можете создать экземпляр этого подкласса, И это именно то, что делает ваш код Java. Ваш Java-код не создает объект ActionListener. Ваш Java-код создает подкласс из ActionListener, который переопределяет actionPerformed и создает экземпляр этого подкласса .

Теперь, конечно, TypeScript поддерживает подклассы, так что вы можете сделать то же самое в TypeScript: создать подкласс, переопределить / реализовать метод, а затем создать экземпляр этого подкласса :

new (class extends ActionListener { 
    actionPerformed(input: string): string {
        return "Hello"
    }
})(input => {
    // Whatever
});

или вы можете сделать это так:

new (class implements ActionListener {
  actionPerformed(input: string): string {
    return "Hello"
  }
});

Детская площадка здесь.

...