Java 8 introduced default methods so that interfaces could gain new methods with a built-in implementation, letting the standard library evolve — most notably by adding Stream support to the Collections Framework — without forcing every existing implementing class to be recompiled or modified.
Key Points: • Before Java 8, adding any method to an interface broke every class implementing it, since Java required all abstract methods to be overridden. • Default methods solve this by providing a body directly in the interface, so old implementations compile and run unchanged. • This mechanism was essential for retrofitting methods like stream(), forEach(), and spliterator() onto the existing Collection and Iterable interfaces. • When a class implements two interfaces that each provide a conflicting default method, the compiler forces the class to override the method explicitly, avoiding the diamond problem of ambiguous inheritance. • Default methods still don't allow interfaces to hold instance fields, preserving the core distinction between interfaces and classes.
Example: The Iterable interface gained a default forEach() method in Java 8; every pre-existing class that implemented Iterable, going back years, automatically supported the new forEach() call without any code changes.
Interview Tip: A concise interview answer is:
"Default methods solve the interface-evolution problem: before Java 8, adding a method to an interface broke every implementing class. By giving the new method a default body, Java could add things like stream() and forEach() to Collection and Iterable without breaking backward compatibility. When two default methods conflict across interfaces, Java forces the implementing class to resolve it explicitly rather than silently picking one."