Lesson 4: Default & Static Methods in Interfaces (Java 8)

Before Java 8, interfaces in Java could only have abstract methods, meaning every implementing class had to provide an implementation for all methods.

Java 8 introduced default and static methods in interfaces, allowing method implementations inside interfaces while maintaining backward compatibility.


1. What Are Default Methods?

A default method is a method in an interface that has a body and uses the default keyword. It allows interfaces to have concrete methods without breaking existing implementations.


Example: Default Method in an Interface

interface Vehicle {
    void start(); // Abstract method

    // Default method with implementation
    default void stop() {
        System.out.println("Vehicle is stopping...");
    }
}

class Car implements Vehicle {
    public void start() {
        System.out.println("Car is starting...");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Calls overridden method
        car.stop();  // Calls default method from interface
    }
}

Output:

Car is starting...
Vehicle is stopping...

stop() is not overridden in Car, so it uses the default method from Vehicle.


2. Why Use Default Methods?

Backward Compatibility – Interfaces can be updated without breaking existing implementations.
Code Reusability – Common logic can be defined once in an interface instead of duplicated in multiple classes.
More Flexible Interfaces – Interfaces can provide default behavior while allowing overriding if needed.


3. Overriding Default Methods

A class can override a default method if a custom implementation is required.

Example: Overriding a Default Method

interface Vehicle {
    default void stop() {
        System.out.println("Vehicle stopping...");
    }
}

class Car implements Vehicle {
    @Override
    public void stop() {
        System.out.println("Car stopping...");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.stop(); // Calls overridden method
    }
}

Output:

Car stopping...

✔ Since Car overrides stop(), the default method is ignored.


4. What Are Static Methods in Interfaces?

A static method inside an interface is a method that belongs to the interface itself and cannot be overridden. It works like a static method in a class.


Example: Static Method in an Interface

interface MathUtils {
    static int add(int a, int b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        int sum = MathUtils.add(5, 10);
        System.out.println("Sum: " + sum);
    }
}

Output:

Sum: 15

Static methods are called using the interface name (MathUtils.add()), not an instance.


5. Default vs. Static Methods in Interfaces

FeatureDefault MethodStatic Method
Keyworddefaultstatic
Can be overridden?✅ Yes❌ No
Called on an instance?✅ Yes❌ No (called on interface)
PurposeProvide default behavior for classesUtility/helper methods in interfaces

6. Resolving Conflicts When Multiple Interfaces Have the Same Default Method

If a class implements two interfaces with the same default method, Java forces the class to override it.

Example: Resolving Default Method Conflict

interface A {
    default void show() {
        System.out.println("A's show method");
    }
}

interface B {
    default void show() {
        System.out.println("B's show method");
    }
}

class C implements A, B {
    @Override
    public void show() {
        System.out.println("C's custom implementation");
    }
}

public class Main {
    public static void main(String[] args) {
        C obj = new C();
        obj.show(); // Must resolve conflict by overriding
    }
}

Output:

C's custom implementation

✔ Java forces C to override show() because A and B have conflicting default methods.

Does Method Conflict Happen Only with Default Methods or Any Method in Interfaces?

The conflict only happens with default methods, not with regular abstract methods.


1. Why Does Conflict Happen Only with Default Methods?

  • Abstract methods (without a body) do not cause conflicts because a class implementing multiple interfaces must provide its own implementation, resolving any ambiguity.
  • Default methods have a body, so Java doesn’t know which one to choose if two interfaces provide the same method implementation.

2. Example: No Conflict with Abstract Methods

If two interfaces have abstract methods with the same name, there is no conflict because the implementing class must define the method itself.

interface A {
    void show(); // Abstract method (no conflict)
}

interface B {
    void show(); // Abstract method (no conflict)
}

class C implements A, B {
    @Override
    public void show() {
        System.out.println("C's custom implementation");
    }
}

public class Main {
    public static void main(String[] args) {
        C obj = new C();
        obj.show(); // No conflict, since C provides its own implementation
    }
}

Output:

C's custom implementation

✔ Since both interfaces only declare show() without a body, C must override it, so there’s no conflict.


3. Example: Conflict with Default Methods

Now, let’s see what happens when both interfaces provide default implementations.

interface A {
    default void show() {
        System.out.println("A's show method");
    }
}

interface B {
    default void show() {
        System.out.println("B's show method");
    }
}

class C implements A, B {
    // ❌ ERROR: Java does not know which show() method to inherit
}

🚨 Compilation Error:

class C inherits unrelated defaults for show() from types A and B

✔ Since both A and B provide default implementations, Java doesn’t know which one to choose.


4. How to Resolve Default Method Conflict?

If two interfaces provide conflicting default methods, the implementing class must explicitly override the method.

class C implements A, B {
    @Override
    public void show() {
        System.out.println("C's custom implementation");
    }
}

✅ Now, C resolves the conflict by providing its own implementation of show().

Alternatively, if you want to use a specific interface’s implementation, you can do this:

class C implements A, B {
    @Override
    public void show() {
        B.super.show(); // Explicitly calling B's default method
    }
}

✅ This calls B‘s show() method instead of A‘s.


Key Takeaways

Abstract methods with the same name do not cause conflicts because the class must override them.
Default methods with the same name do cause conflicts, as Java doesn’t know which one to inherit.
To resolve conflicts, the implementing class must override the method or explicitly call the desired default method.


Lesson Reflection

  1. Why do you think Java introduced default methods in interfaces?
  2. How do static methods in interfaces differ from utility classes (like Math or Collections)?
  3. Can you think of a real-world scenario where a default or static method in an interface would be useful?

next Java 8 feature: New Date & Time API (java.time package)

Java Sleep