Introduced in Java 8, default methods are a way of specifying an implementation inside an interface. This could be used to avoid the typical “Base” or “Abstract” class by providing a partial implementation of an interface, and restricting the subclasses hierarchy.
For example, it’s possible to implement the Observer-Listener pattern directly into the interface, providing more flexibility to the implementing classes.
interface Observer {
void onAction(String a);
}
interface Observable{
public abstract List getObservers();
public default void addObserver(Observer o){ getObservers().add(o); }
public default void notify(String something ){ for( Observer l : getObservers() ){ l.onAction(something); } }
}
Now, any class can be made “Observable” just by implementing the Observable interface, while being free to be part of a different class hierarchy.
abstract class Worker{
public abstract void work();
}
public class MyWorker extends Worker implements Observable {
private List myObservers = new ArrayList();
@Override public List getObservers() { return myObservers; }
@Override public void work(){ notify(“Started work”);
// Code goes here...
notify("Completed work");
}
public static void main(String[] args) {
MyWorker w = new MyWorker();
w.addListener(new Observer() {
@Override
public void onAction(String a) {
System.out.println(a + " (" + new Date() + ")");
}
});
w.work();
}
}