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.

Observer pattern implementation

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

}

}