Default Methods
Default methods were introduced in Java 8 to allow interfaces to have method implementations. They enable interface evolution without breaking existing implementations and are a key enabler for functional programming features (lambdas, streams). This is a frequent interview topic, especially around diamond problem resolution.
What Is a Default Method?
A default method is a method in an interface that has a method body and is declared using the default keyword.
interface Vehicle {
default void start() {
System.out.println("Vehicle started");
}
}
- ✔ Method has implementation
- ✔ Classes implementing the interface inherit it automatically
Why Default Methods Were Introduced
Before Java 8:
- Interfaces could have only abstract methods
- Adding a new method broke all implementing classes
With Java 8:
- Default methods allow backward compatibility
- Existing classes need no change
Syntax Rules
interface InterfaceName {
default returnType methodName() {
// implementation
}
}
- ✔ Must have a body
- ✔ Cannot be abstract
- ✔ Implicitly public
Using Default Methods
Interface
interface Printer {
default void print() {
System.out.println("Printing...");
}
}
Implementing Class
class LaserPrinter implements Printer {
// no need to override print()
}
✔ print() available automatically
Overriding Default Methods
Implementing classes can override default methods.
class InkjetPrinter implements Printer {
@Override
public void print() {
System.out.println("Inkjet printing...");
}
}
✔ Class version takes precedence
Default Methods vs Abstract Methods
| Aspect | Default Method | Abstract Method |
|---|---|---|
| Has body | ✔ Yes | ❌ No |
| Mandatory override | ❌ No | ✔ Yes |
| Introduced | Java 8 | Java 1.0 |
| Backward compatible | ✔ Yes | ❌ No |
Default Methods vs Static Methods in Interface
| Aspect | Default Method | Static Method |
|---|---|---|
| Called via | Object | Interface name |
| Inherited | ✔ Yes | ❌ No |
| Overridable | ✔ Yes | ❌ No |
interface Utils {
default void show() {}
static void help() {}
}
Diamond Problem & Default Methods (Very Important)
Scenario: Two Interfaces, Same Default Method
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
class Test implements A, B {
// ❌ Compilation error unless overridden
}
Resolving the Conflict
class Test implements A, B {
@Override
public void show() {
A.super.show(); // or B.super.show()
}
}
- ✔ Class must override
- ✔ Explicitly choose which interface method to call
Interface vs Class Priority Rule (Interview Rule)
- Class methods win over interface default methods
- More specific interface wins
- If ambiguity → class must override
class Parent {
public void show() {}
}
interface Child {
default void show() {}
}
✔ Parent.show() is used
Default Methods & Functional Interfaces
- ✔ Functional interfaces can have default methods
- ✔ Only one abstract method allowed
@FunctionalInterface
interface Task {
void execute();
default void log() {
System.out.println("Logging...");
}
}
✔ Still a functional interface
Real-World Usage Examples
- Collection → forEach()
- List → sort()
- Iterator → forEachRemaining()
These were added without breaking old code.
Common Beginner Mistakes
- Forgetting default keyword
- Assuming default methods are mandatory
- Confusing static and default methods
- Not resolving diamond conflict
- Overusing default methods
Best Practices
- Use default methods sparingly
- Avoid adding business logic to interfaces
- Prefer abstract classes for stateful behavior
- Use default methods for common behavior
- Always resolve ambiguity explicitly
Interview-Ready Answers
Short Answer
Default methods allow interfaces to have method implementations.
Detailed Answer
In Java 8, default methods were introduced to allow interfaces to provide method implementations using the default keyword. They enable backward compatibility when interfaces evolve and support functional programming features, while still allowing implementing classes to override the default behavior.
Key Takeaway
Default methods make interfaces evolvable. They balance flexibility and compatibility, but should be used carefully to avoid design complexity.
Default Methods Examples (Quick Reference)
1. Basic Default Method in Interface
interface Vehicle {
default void start() {
System.out.println("Vehicle starting");
}
}
class Car implements Vehicle {
}
class Demo {
public static void main(String[] args) {
new Car().start();
}
}
Output
Vehicle starting
2. Class Inheriting Default Method Automatically
interface Printer {
default void print() {
System.out.println("Printing...");
}
}
class HPPrinter implements Printer {
}
Explanation
- Implementing class need not override
- Default method is inherited
3. Overriding Default Method in Class
interface Printer {
default void print() {
System.out.println("Default print");
}
}
class LaserPrinter implements Printer {
@Override
public void print() {
System.out.println("Laser print");
}
}
4. Calling Interface Default Method from Override
interface Printer {
default void print() {
System.out.println("Default print");
}
}
class InkPrinter implements Printer {
public void print() {
Printer.super.print();
System.out.println("Ink print");
}
}
Output
Default print
Ink print
5. Multiple Interfaces with Same Default Method (Conflict)
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
class Demo implements A, B {
public void show() {
System.out.println("Resolved");
}
}
Rule
Must override to resolve ambiguity.
6. Resolving Conflict Using InterfaceName.super
class Demo implements A, B {
public void show() {
A.super.show();
B.super.show();
}
}
7. Default Method vs Abstract Method
interface A {
default void run() {
System.out.println("Default run");
}
}
interface B {
void run();
}
class Demo implements A, B {
public void run() {
System.out.println("Implemented run");
}
}
Rule
- Abstract method wins
- Must implement
8. Default Method vs Class Method (Class Wins)
interface A {
default void test() {
System.out.println("Interface");
}
}
class Base {
public void test() {
System.out.println("Class");
}
}
class Demo extends Base implements A {
}
Output
Class
9. Default Method Cannot Override Object Methods
interface A {
// default String toString() { } ❌ not allowed
}
Reason
Object methods cannot be default methods.
10. Default Method with Parameters
interface Calculator {
default int add(int a, int b) {
return a + b;
}
}
class Demo {
public static void main(String[] args) {
Calculator c = new Calculator() {};
System.out.println(c.add(5, 7));
}
}
11. Default Method Using Private Helper Method (Java 9+)
interface Logger {
default void log() {
helper();
}
private void helper() {
System.out.println("Logging...");
}
}
12. Default Method + Lambda (Not Used Together)
@FunctionalInterface
interface Task {
void run();
default void info() {
System.out.println("Task info");
}
}
Note
Still functional (only one abstract method).
13. Default Method in Functional Interface
@FunctionalInterface
interface Printer {
void print();
default void status() {
System.out.println("Ready");
}
}
14. Using Default Method via Interface Reference
Printer p = () -> System.out.println("Printing");
p.status();
p.print();
15. Multiple Default Methods (No Conflict)
interface A {
default void a() {}
}
interface B {
default void b() {}
}
class Demo implements A, B {
}
16. Default Method Evolution Use Case (Java 8 Reason)
interface ListV1 {
void add();
}
// Later version
interface ListV2 {
default void size() {
System.out.println("Size");
}
}
Explanation
Prevents breaking existing implementations.
17. Default Method Cannot Access Instance Fields
interface A {
default void test() {
// System.out.println(x); ❌ no instance fields
}
}
18. Default Method Access Modifiers
interface A {
default void a() {} // public by default
// protected/private ❌ not allowed (Java 8)
}
19. Real Interview Trap
interface A {
default void run() {}
}
class Demo implements A {
// No override needed
}
Interview Question
Is override mandatory? → ❌ No
20. Default Method vs Static Method
interface A {
default void d() {
System.out.println("Default");
}
static void s() {
System.out.println("Static");
}
}
A a = new A() {};
a.d();
// a.s(); ❌ not allowed
A.s(); // ✅
21. Default Method with Interface Inheritance
interface A {
default void show() {
System.out.println("A");
}
}
interface B extends A {
}
class Demo implements B {
}
22. Overriding Default Method as Abstract
interface A {
default void show() {}
}
interface B extends A {
void show(); // makes it abstract again
}
23. Default Method Cannot Be final
interface A {
// default final void test() {} ❌
}
24. Default Method Real-World Usage
// Java Collections (forEach, removeIf)
// Comparator.thenComparing()
// Iterable.forEach()
25. Interview Summary – Default Methods
default method = concrete method in interface
Key Points
- Introduced in Java 8
- Enables interface evolution
- Class method > interface default
- Conflict must be resolved explicitly
- Supports code reuse without breaking changes