Reputation: 100416
With Java we can create an instance of the ActionListener class which has an abstract method, something like this (it has been awhile):
new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// whatever
}
}
using TypeScript, this is the closest I can get to it:
export abstract class ActionListener {
constructor(f: any) {
this.actionPerformed = f;
}
abstract actionPerformed(input: string): string;
}
new ActionListener(input => {
});
there are at least 2 problems:
If you use an abstract method with TS, the class has to abstract (I think with Java you could have abstract methods which could be implemented later).
I don't know how to tie/tether the type of the input function f, to the type of the parse method.
Does anyone know if there is a way to do this with TS?
Perhaps we can't use abstract
with TS, and have to do it more like this:
type ActionPerformed = (input: string) => string;
export class ActionListener {
parse: ActionPerformed;
constructor(f: ActionPerformed) {
this.parse = f;
}
}
new ActionListener(input => {
return 'foo';
});
Upvotes: 0
Views: 1328
Reputation: 369594
With Java we can create an instance of the ActionListener class which has an abstract method
No, you can't create an instance of a class which has an abstract method. What is supposed to happen when you call that abstract method?
What you can do is you can create a subclass of that abstract class which implements that abstract method, and you can create an instance of that subclass. And that is exactly what your Java code is doing. Your Java code is not instantiating an object of ActionListener
. Your Java code is creating a subclass of ActionListener
which overrides actionPerformed
and it instantiates that subclass.
Now, of course TypeScript supports subclassing, so you can do the exact same thing in TypeScript: create a subclass, override/implement the method, then instantiate that subclass:
new (class extends ActionListener {
actionPerformed(input: string): string {
return "Hello"
}
})(input => {
// Whatever
});
or you can do it like so:
new (class implements ActionListener {
actionPerformed(input: string): string {
return "Hello"
}
});
Upvotes: 5
Reputation: 175088
This is not required in JavaScript or TypeScript. Java has no concept of functions as first class objects, lambdas are just sugar for instantiated objects that implement a functional interface.
As such, the idiomatic way in JS/TS is to not have a class here, but to simply pass a callback function:
interface ActionListener {
(ev: Event) => void;
}
function iNeedAnActionHandler(actionListener: ActionListener) {
// do stuff
const ev = new Event(); // whatever
actionListener(ev);
}
No need for clumsy classes and interface implementation just to pass a callback.
Upvotes: 1