Java Default Methods: 10 Important Cases Every Java Developer Should Know (With Examples)
Java 8 introduced default methods in interfaces, one of the most significant improvements to the language. Before Java 8, interfaces could only contain abstract methods, meaning every implementing…
Java 8 introduced default methods in interfaces, one of the most significant improvements to the language. Before Java 8, interfaces could only contain abstract methods, meaning every implementing class had to provide its own implementation.
With default methods, interfaces can now include method implementations using the default keyword.
This solved an important problem: how can new methods be added to existing interfaces without breaking millions of existing classes?
For example, imagine an interface that has been used by thousands of developers worldwide. If a new abstract method is added, every implementing class would immediately fail to compile. Default methods solve this by providing a ready-made implementation that existing classes automatically inherit.
Although default methods make interfaces more flexible, they also introduce several rules regarding inheritance and method resolution. These rules are frequently asked in Java interviews because they test your understanding of multiple inheritance through interfaces.
In this article, we’ll cover the 10 most important default method scenarios, understand why each behaves the way it does, and learn the rules Java follows when resolving method conflicts.
Case 1: Class Does Not Override the Default Method
If a class implements an interface but does not override its default method, the class automatically inherits the implementation.
Example
interface Animal {
default void sound() {
System.out.println("Animal Sound");
}
}
class Dog implements Animal {
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound();
}
}
Output
Animal Sound
Explanation
Since Dog does not provide its own implementation of sound(), Java simply uses the default implementation defined inside the interface.
Think of it as inheriting a concrete method from the interface.
Case 2: Class Overrides the Default Method
A class is always free to provide its own implementation.
Example
interface Animal {
default void sound() {
System.out.println("Animal Sound");
}
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println("Dog Barks");
}
}
Output
Dog Barks
Explanation
Whenever the implementing class defines the same method, the class implementation always takes priority over the interface’s default implementation.
This follows normal object-oriented programming principles where child implementations override inherited ones.
Case 3: Two Interfaces Have the Same Default Method (Diamond Problem)
Now let’s consider multiple inheritance through interfaces.
Example
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
class C implements A, B {
}
Compilation Error
Duplicate default methods named show()
Why Does This Happen?
Class C inherits two implementations of show():
- One from interface
A - Another from interface
B
Java cannot automatically decide which implementation should be used.
Unlike classes, interfaces allow multiple inheritance, so Java forces the programmer to resolve the ambiguity manually.
Case 4: Resolve the Ambiguity by Overriding
The simplest solution is to override the method.
Example
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
class C implements A, B {
@Override
public void show() {
System.out.println("C");
}
}
Output
C
Explanation
Once the class provides its own implementation, the ambiguity disappears.
Java simply calls the overridden method.
Case 5: Call a Specific Interface’s Default Method
Sometimes you want to reuse one interface’s implementation instead of writing new code.
Java allows this using:
InterfaceName.super.methodName();
Example
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
class C implements A, B {
@Override
public void show() {
A.super.show();
}
}
Output
A
You can also choose the other interface.
class C implements A, B {
@Override
public void show() {
B.super.show();
}
}
Output
B
Explanation
A.super.show() explicitly tells Java to invoke the default implementation from interface A.
Similarly,
B.super.show();
calls the implementation from interface B.
Case 6: Call Both Interface Default Methods
Nothing prevents you from calling both implementations.
Example
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
class C implements A, B {
@Override
public void show() {
A.super.show();
B.super.show();
}
}
Output
A
B
Explanation
Since you explicitly specify which interface to use, Java has no ambiguity.
This technique is useful when both implementations contain useful behavior.
Case 7: Class Method Wins Over Interface Default Method
What if a superclass already contains a method with the same signature?
Example
class Parent {
public void show() {
System.out.println("Parent");
}
}
interface A {
default void show() {
System.out.println("Interface");
}
}
class Child extends Parent implements A {
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.show();
}
}
Output
Parent
Explanation
Java follows an important rule:
Methods inherited from a class always take precedence over default methods inherited from interfaces.
This ensures that traditional class inheritance remains stronger than interface inheritance.
Case 8: Child Class Overrides Everything
The child class can still provide its own implementation.
Example
class Parent {
public void show() {
System.out.println("Parent");
}
}
interface A {
default void show() {
System.out.println("Interface");
}
}
class Child extends Parent implements A {
@Override
public void show() {
System.out.println("Child");
}
}
Output
Child
Explanation
The overridden method in the child class has the highest priority.
Java follows the following precedence:
Child Class
↓
Parent Class
↓
Interface Default Method
Case 9: Calling the Parent Class Method Using super
Sometimes you want to reuse the parent implementation.
Example
class Parent {
public void show() {
System.out.println("Parent");
}
}
interface A {
default void show() {
System.out.println("Interface");
}
}
class Child extends Parent implements A {
@Override
public void show() {
super.show();
}
}
Output
Parent
Explanation
The keyword
super.show();
always invokes the immediate superclass implementation.
It never refers to an interface method.
Case 10: Calling Both Parent Class and Interface Default Method
You can even combine both implementations.
Example
class Parent {
public void show() {
System.out.println("Parent");
}
}
interface A {
default void show() {
System.out.println("Interface");
}
}
class Child extends Parent implements A {
@Override
public void show() {
super.show(); // Parent class method
A.super.show(); // Interface default method
}
}
Output
Parent
Interface
Explanation
Notice the difference:
super.show();
calls the superclass implementation.
Whereas
A.super.show();
calls the default implementation from interface A.
These are two completely different forms of super.
Method Resolution Rules (Remember These for Interviews)
Whenever Java needs to decide which implementation to execute, it follows these rules in order:
Rule 1: Child Class Wins
If the class overrides the method, Java always calls the class implementation.
Rule 2: Parent Class Wins Over Interface
If the method exists in a superclass, Java prefers the superclass implementation over the interface’s default method.
Rule 3: Multiple Interface Defaults Must Be Resolved Explicitly
If two interfaces provide the same default method, Java reports a compilation error until the implementing class resolves the conflict.
Rule 4: Use InterfaceName.super.method() to Access a Specific Default Method
You can explicitly invoke any interface’s default implementation using:
InterfaceName.super.method();
This removes any ambiguity.
Summary Table
| Case | Situation | Result |
|---|---|---|
| 1 | Class doesn’t override | Interface default method executes |
| 2 | Class overrides | Class method executes |
| 3 | Two interfaces, same default method | Compilation error |
| 4 | Override to resolve conflict | Class method executes |
| 5 | A.super.show() | Calls interface A’s implementation |
| 6 | Call both interfaces | Both methods execute |
| 7 | Parent class + interface | Parent class method wins |
| 8 | Child overrides everything | Child method executes |
| 9 | super.show() | Calls parent class method |
| 10 | super.show() + A.super.show() | Calls both parent and interface methods |
Final Thoughts
Default methods made Java interfaces far more powerful by allowing method implementations without breaking existing code. However, they also introduced new method resolution rules that every Java developer should understand.
The key takeaway is simple:
- Class methods always have higher priority than interface default methods.
- Child class methods override everything.
- If multiple interfaces provide the same default method, Java requires you to resolve the ambiguity manually.
- Use
InterfaceName.super.method()whenever you want to invoke a specific interface’s default implementation.
Mastering these 10 scenarios will help you write cleaner Java code and confidently answer one of the most common Java interview topics.