Default Methods in Java – Behaviour in Interfaces
A default method is an interface method with a body, declared with the default keyword. Every class that implements the interface inherits it automatically and may override it. Default methods were added in Java 8 so that interfaces could gain new methods without breaking the classes that already implement them.
This tutorial covers the syntax, the interface evolution problem default methods solve, the rules for resolving conflicts (the "diamond problem") and how default methods compare with abstract classes and static interface methods.
1. Syntax and a First Example
interface InterfaceName {
default ReturnType methodName(Parameters) {
// body: can call the interface's other methods
}
}
public class DefaultMethodBasics {
interface Vehicle {
String name();
int wheels();
default String describe() { // inherited by every implementation
return name() + " with " + wheels() + " wheels";
}
default void honk() { System.out.println(name() + ": Beep!"); }
}
static class Car implements Vehicle {
public String name() { return "Car"; }
public int wheels() { return 4; }
// uses both defaults as they are
}
static class Bike implements Vehicle {
public String name() { return "Bike"; }
public int wheels() { return 2; }
@Override public void honk() { System.out.println(name() + ": Ring ring!"); } // overrides
}
public static void main(String[] args) {
for (Vehicle v : new Vehicle[] { new Car(), new Bike() }) {
System.out.println(v.describe());
v.honk();
}
}
}
Car with 4 wheels Car: Beep! Bike with 2 wheels Bike: Ring ring!
describe()is written once in the interface and works for every vehicle, because it calls the abstract methods each class implements.Carinheritshonk();Bikeoverrides it.- Default methods are implicitly
public. They cannot befinal,staticorsynchronized.
2. Why Default Methods Exist: Interface Evolution
Before Java 8, adding a method to a published interface broke every implementing class, because each one suddenly failed to implement the new abstract method. Java 8 needed to add stream and lambda support to Collection, List, Map and others, which millions of classes implement. Default methods solved this:
import java.util.*;
public class InterfaceEvolution {
// Version 1 of a library interface had only find(); version 2 added findOrDefault()
interface Repository<T> {
Optional<T> find(String id);
// Added later as a default method: old implementations keep compiling
default T findOrDefault(String id, T fallback) {
return find(id).orElse(fallback);
}
}
// An "old" implementation written before findOrDefault existed
static class UserRepo implements Repository<String> {
private final Map<String, String> users = Map.of("1", "Asha", "2", "Ravi");
public Optional<String> find(String id) { return Optional.ofNullable(users.get(id)); }
}
public static void main(String[] args) {
UserRepo repo = new UserRepo();
System.out.println(repo.findOrDefault("1", "guest"));
System.out.println(repo.findOrDefault("9", "guest"));
// The JDK did the same in Java 8: forEach, removeIf, sort and getOrDefault are defaults
List<Integer> nums = new ArrayList<>(List.of(5, 3, 8, 1, 6));
nums.removeIf(n -> n < 4); // default in Collection
nums.sort(Comparator.reverseOrder()); // default in List
nums.forEach(n -> System.out.print(n + " "));
System.out.println();
}
}
Asha guest 8 6 5
JDK examples of default methods include Iterable.forEach, Collection.removeIf and stream, List.sort, Map.getOrDefault, Map.computeIfAbsent and Comparator.reversed.
3. Conflicts and the Diamond Problem
A class can implement several interfaces, so it might inherit two default methods with the same signature. Java resolves this with three rules:
- Classes win: a method declared in the class or any superclass takes priority over interface defaults.
- More specific interface wins: if
B extends Aand both define the default,B's version is used. - Otherwise the class must override the method; inside, it can call a particular version with
InterfaceName.super.method().
public class DiamondConflict {
interface Camera { default String start() { return "Camera ready"; } }
interface Phone { default String start() { return "Phone ready"; } }
// Both interfaces supply start(): the class MUST resolve the conflict
static class SmartPhone implements Camera, Phone {
@Override
public String start() {
return Phone.super.start() + " + " + Camera.super.start(); // pick or combine
}
}
// Rule 1: a class method always wins over an interface default
static class Device { public String start() { return "Device ready (class wins)"; } }
static class Tablet extends Device implements Camera { }
// Rule 2: the more specific interface wins
interface ProCamera extends Camera { default String start() { return "ProCamera ready (more specific wins)"; } }
static class Dslr implements Camera, ProCamera { }
public static void main(String[] args) {
System.out.println(new SmartPhone().start());
System.out.println(new Tablet().start());
System.out.println(new Dslr().start());
}
}
Phone ready + Camera ready Device ready (class wins) ProCamera ready (more specific wins)
Without the override in SmartPhone, compilation fails with "types Camera and Phone are incompatible; class SmartPhone inherits unrelated defaults for start()".
4. Default Methods vs Static Interface Methods
| Aspect | Default method | Static method |
|---|---|---|
| Keyword | default | static |
| Called on | An object: list.sort(...) | The interface: Comparator.naturalOrder() |
| Inherited by implementing classes | Yes | No |
| Can be overridden | Yes | No |
Can use this / abstract methods | Yes | No |
5. Default Methods vs Abstract Classes
Default methods make interfaces look similar to abstract classes, but important differences remain:
- Interfaces still have no instance state (fields) and no constructors; default methods can only work through other methods.
- A class can implement many interfaces but extend only one class.
- Default methods are always public; abstract classes can have protected and private members with state.
Use default methods for convenience behaviour built on the interface's own methods, and an abstract class when you need shared state or constructors.
6. Best Practices
- Keep default methods simple and based on the interface's abstract methods.
- Use them to evolve APIs carefully: a new default can still clash with an existing method of the same name in some implementation.
- Do not provide defaults for
equals,hashCodeortoString; this is not allowed, because class methods always win. - Use private interface methods (Java 9+) to share code between default methods.
7. Summary
- Default methods are interface methods with bodies, declared with
default(Java 8+). - Implementing classes inherit them and may override them.
- They allow interfaces to evolve without breaking existing implementations.
- Conflicts: class methods win, then the more specific interface; otherwise override and use
X.super.m(). - Interfaces with defaults still have no state or constructors, unlike abstract classes.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is a default method in Java?
An interface method with an implementation, declared with the default keyword. Implementing classes inherit it and can override it.
Q2. Why were default methods introduced?
To let interfaces such as Collection and List gain new methods in Java 8 (like forEach and stream) without breaking existing implementations.
Q3. Can a default method be overridden?
Yes. An implementing class or sub-interface can override it; the override must be public.
Q4. Can a default method be static?
No. A method is either default (instance-level, inherited) or static (called on the interface), not both.
Q5. Can a default method be final?
No. Interfaces cannot prevent implementations from overriding default methods.
Q6. What is the diamond problem with default methods?
When a class inherits the same default method from two unrelated interfaces. Java requires the class to override the method to resolve the ambiguity.
Q7. How do I call a specific interface's default method?
Use InterfaceName.super.methodName() inside the implementing class's method.
Q8. Does a class method override an interface default method?
Yes. Methods from the class hierarchy always take priority over interface defaults.
Q9. Can a default method access instance variables?
Not directly, because interfaces have no instance fields. It can call the interface's other methods, which implementations use to expose state.
Q10. Can a functional interface have default methods?
Yes, any number, as long as it has exactly one abstract method. Function.andThen is an example.
Q11. Can I define equals() as a default method?
No. The compiler forbids default methods that override equals, hashCode or toString, because the Object versions would always win.
Q12. Can an abstract class override a default method with an abstract one?
Yes. An abstract class or sub-interface can redeclare a default method as abstract, forcing concrete subclasses to implement it.
Q13. What is the difference between default methods and abstract classes?
Interfaces with default methods have no instance fields or constructors and allow multiple implementation. Abstract classes can hold state and constructors but allow only single inheritance.
Q14. Which JDK methods are default methods?
Examples include Iterable.forEach, Collection.stream, Collection.removeIf, List.sort, Map.getOrDefault, Map.merge and Comparator.thenComparing.
Q15. Can default methods be synchronized?
No. The synchronized modifier is not allowed on default methods; use a synchronized block inside if needed.
Q16. Are default methods public?
Yes, always. For non-public helper methods, use private interface methods (Java 9+).
Q17. Can a sub-interface override a default method?
Yes. It can provide a new default implementation or redeclare the method as abstract.
Q18. Do default methods support polymorphism?
Yes. Calls are dispatched at run time, so an overriding implementation in a class is used when present.
Q19. Can adding a default method break existing code?
Rarely, but yes: if an implementing class already has a method with the same signature but a different return type or contract, or if it creates a new diamond conflict.
Q20. What are defender or virtual extension methods?
Early names for default methods used during their design for Java 8.