Detailed explanation
Java interfaces can contain both default methods and static methods, introduced in Java 8, but they serve different purposes. A default method defines instance behaviour with a concrete implementation that implementing classes normally inherit. A static method defines an operation belonging to the interface itself. Both have method bodies, so the key distinction is not whether they provide implementation, but whether they participate in instance inheritance and polymorphism.
In the Vehicle example, default void honk() supplies shared behaviour for Vehicle implementations. If Car implements Vehicle without providing honk(), new Car().honk() prints "Beep". Car can override it with a public instance method. For Vehicle v = new Car(), calling v.honk() uses runtime method dispatch: an overriding implementation in Car takes precedence over the interface default. A default method has an instance receiver, so it can use this and invoke other instance methods declared by the interface. However, interfaces cannot declare instance fields, so the default method cannot rely on interface-owned per-object state.
The static createDefault() method is instead called as Vehicle.createDefault(). It can construct and return a Car, assuming Car is a valid concrete Vehicle implementation. Interface static methods are not inherited by implementing classes or subinterfaces, so neither Car.createDefault() nor v.createDefault() can access Vehicle's static method. They have no this reference and cannot be overridden. If Car declares a method with the same signature, that is a separate declaration, not an override of the interface method. Static method selection does not depend on the runtime type of an object.
Default methods matter when evolving APIs because they can add behaviour without forcing every existing implementation to supply that method immediately, although inheritance conflicts remain possible. An inherited concrete superclass method takes precedence over an interface default; defaults from unrelated interfaces require an explicit override to resolve the conflict. Static methods are useful for interface-related factories, validation, and utilities. In interviews, demonstrate the distinction through call syntax, inheritance, overriding, and runtime dispatch rather than merely saying that both methods have implementations.
Key points to remember
- A default method provides inherited instance behaviour and can be overridden with a public instance method.
- A static method belongs to the interface and is called using the declaring interface's name.
- Interface static methods are not inherited by implementing classes or subinterfaces.
- Default methods participate in runtime polymorphism; static methods do not.
- Default methods can use this; static methods have no instance receiver.
Common mistakes candidates make
- Calling an interface static method through an implementing class or an object reference.
- Claiming that a same-signature method in an implementing class overrides the interface's static method.
- Assuming default methods always avoid implementation changes, ignoring conflicts between unrelated interface defaults.
Likely follow-up questions
What happens if two unrelated interfaces provide the same default method?
A class implementing both must explicitly override the method to resolve the conflict. For an eligible direct superinterface, it can call a particular default implementation using InterfaceName.super.methodName().
Can an interface static method be overridden or hidden by an implementing class?
No: interface static methods are not inherited, so a same-signature method in the implementing class neither overrides nor hides that interface method. It is a separate declaration accessed according to the class's own method rules.
Can a default method override equals(), hashCode(), or toString()?
An interface cannot provide a default method override-equivalent to a non-private method of Object, so these default implementations are prohibited. An interface may declare these methods abstractly, but their implementations must come from the class hierarchy.
Interview tip: Use Vehicle to contrast v.honk() with Vehicle.createDefault(), then explain inheritance and overriding in one clear comparison.
