In Java 8, the concept of default methods was introduced — these are methods with implementations declared inside an interface. They allow adding new methods to interfaces without breaking compatibility with existing implementations.
Syntax:
public interface MyInterface { default void printHello() { System.out.println("Hello!"); } }
Features and nuances:
Object class (such as equals, hashCode).What happens if a class implements two interfaces with the same default method and does not override that method?
Answer: The compiler will throw an error "class... inherits unrelated defaults for ... from types ... and ...", and it will require explicitly implementing that method in the class.
Example:
interface A { default void doSomething() { System.out.println("A"); } } interface B { default void doSomething() { System.out.println("B"); } } class C implements A, B {} // Compilation error!
Solution:
class C implements A, B { @Override public void doSomething() { A.super.doSomething(); // or B.super.doSomething() } }
Story
In a team project for API migration, a default method was added to a common interface. The old implementations of the interface did not override the new method, leading to unexpected behavior, as the default implementation was executed instead of the expected logic. As a result, users noticed a drop in functionality.
Story
When extending a library, one of the developers added a default method with business logic to a common interface. The subsequent addition of a similar method with different behavior in another interface caused an inheritance conflict, preventing the new implementations from compiling.
Story
A developer attempted to use a default method named
hashCodein an interface, expecting it to affect the overriding of the method in subclass implementations, but the compiler did not allow this. This led to a lengthy investigation into the cause of the error and a redesign of the interface structure.