Hintergrund zur Einführung von Default-Methoden war die Notwendigkeit, die Java-API von Schnittstellen im Nachhinein ohne nennenswerte Compilerfehler verändern zu können. Ideal ist, wenn neue Default-Methoden hinzukommen und Standard-Verhalten definieren, und es dadurch zu keinem Compiler-Fehler für implementierende Klassen kommt, oder zu Fehlern bei Schnittstellen, die erweiterte Schnittstellen erweitern.
In unserem Beispiel haben wir eine Schnittstelle Buyable für käufliche Dinge vorgesehen. Dazu müssen die „Dinge“ aber erst einmal einen Preis haben. Führen wir eine weitere Schnittstelle Priced ein:
interface Priced {}
interface Buyable extends Priced {
double price();
}
Die Schnittstelle Prices hat keine Vorgaben, sie soll nur Typen markieren. Nehmen wir an, es gibt viele Klassen, die Priced und auch Buyable implementieren.
In der Entwicklung stellt sich nun heraus, dass Priced auch eine Methode double price() bekommen soll. Kann die Methoden einfach als abstrakte Methode ohne Probleme hinzugekommen werden? Nicht wirklich, denn wenn es viele implementierende Klassen gibt, wird es auch viele Compilerfehler geben. Aber zur problemlosen Erweiterung von Schnittstellen sind Default-Methoden da. Kann also eine Default-Methode price() in Priced aufgenommen werden, also die Schnittstelle nachträglich verändert werden, ohne dass es Compilerfehlen gibt? Ja, das geht.
interface Priced {
default double price() { return -1; }
}
interface Buyable extends Priced {
@Override double price();
}
Interessant sind zwei Details. Zunächst einmal ist in Buyable die Methode weiterhin abstrakt, was bedeutet, eine abstrakte Methode überschreib eine Default-Methode. Klassen, die Buyable implementieren, müssen also weiterhin eine price()-Methode implementieren, wenn sie nicht selbst abstrakt sein wollen. Die nachträgliche Veränderung der Oberschnittstelle hat also keine Auswirkungen auf die anderen Klassen. Im Nachhinein kann aber zur Dokumentation die Annotation @Override and die Unterschnittstelle gesetzt werden. Das ist schon spannend, dass die Implementierung einer Default-Methode weggenommen werden kann. Bei der Sichtbarkeit ist das zum Beispiel nicht möglich: ist eine Methode einmal öffentlich, kann eine Unterklasse die Sichtbarkeit nicht einschränken.