In Java, interfaces with a single abstract method (i.e., SAM types or functional interfaces) can be elegantly implemented with lambda instead of an anonymous class:
// SAM ActionListener with anonymous implementation
button.addActionListener(
new ActionListener(){
public void actionPerformed(Event e){
System.out.println("button via anon!");
}
}
);
can be replaced with:
// SAM ActionListener with lambda implementation
button.addActionListener(
e -> System.out.println("button via lambda!")
);
But for interfaces with multiple abstract methods, lambda cannot be directly applied. For example, java.awt.event.WindowListener
has seven methods. But often a chunk a code is only interested in defining one of these seven methods.
To implement the behavior with an anonymous class override, we can:
// non-SAM with adapter implementation with override
window.addWindowListener(
new WindowAdapter() {
@Override
public void windowOpened(Event e){
System.out.println("WindowAdapter opened via override!");
}
}
);
but is there a more elegant way with lambdas?
@FunctionalInterface
public interface ActionListener {
void actionPerformed(Event e);
}
public interface WindowListener {
void windowOpened(Event e);
void windowClosing(Event e);
}
public class WindowAdapter implements WindowListener {
public void windowOpened(Event e){
System.out.println("windowOpened in adapter!");
}
public void windowClosing(Event e){
System.out.println("windowClosing in adapter!");
}
}
Note: @maythesource.com asked a similar, but broader question: "What would someone do with a MouseListener if they wanted to implement multiple methods within the anonymous class?" The most upvoted and accepted answer is to use an anonymous implementation. My question is about an elegant lambda solution for non-SAM types. Therefore, this question is not a duplicate of Java 8 Lambda Expressions - what about multiple methods in nested class.