Mastering Java Beyond Classes — Part 2: Default and Static Methods in Interfaces

Before Java 8, interfaces could only contain abstract methods. This limitation made it difficult to enhance APIs without breaking existing implementations.

To address this challenge, Java introduced default and static methods in interfaces.

In this article, you’ll learn:

  • What default and static methods are
  • Why were they introduced
  • How to implement and use them
  • Common pitfalls and best practices

a) Default Methods in Interfaces

A default method is a method defined within an interface that includes a body. It enables interfaces to provide standard implementations that implementing classes can use or override.

Syntax

interface Vehicle {
default void start() {
System.out.println("Engine starting...");
}
}

Using a Default Method

interface Vehicle {
default void start() {
System.out.println("Engine starting...");
}
}

class Car implements Vehicle {
}

public class TestDefaultMethod {
public static void main(String[] args) {
// Using the subclass as the reference type
Car car = new Car();
car.start();

// Using the interface as the reference type
Vehicle myVehicle = new Car();
myVehicle.start();
}
}

We can use both ways above to call the start() method.

The Car class inherits the default method from the Vehicle interface.

No implementation is required unless customization is needed.

Also, we can use the interface as the reference and call the method.

Overriding Default Methods

Implementing classes can override default methods to provide their own behaviour.

interface Vehicle {
default void start() {
System.out.println("Engine starting...");
}
}

class ElectricCar implements Vehicle {
@Override
public void start() {
System.out.println("Battery powering the car...");
}
}

public class TestOverride {
public static void main(String[] args) {
Vehicle car = new ElectricCar();
car.start();
}
}

Output

Battery powering the car...

Diamond Problem with Default Methods

When a class implements multiple interfaces that contain the same default method, ambiguity occurs. This is known as the diamond problem.

interface A {
default void show() {
System.out.println("Interface A");
}
}

interface B {
default void show() {
System.out.println("Interface B");
}
}

class Test implements A, B {
@Override
public void show() {
// Resolves the conflict here
A.super.show();
B.super.show();
}
}

public class Main {
public static void main(String[] args) {
new Test().show();
}
}

Output

Interface A
Interface B

b) Static Methods in Interfaces

A static method belongs to the interface itself rather than to implementing classes. These methods are typically used for utility or helper functions.

Syntax

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

Using a Static Method

Try to get the answer.

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

public class TestStaticMethod {
public static void main(String[] args) {
int result = Calculator.add(5, 3);
System.out.println("Sum: " + result);
}
}

Static methods are called using the interface name. They are not inherited by implementing classes.

Output

Sum: 8

Question 1

What will be the output?

interface Greeting {
default void sayHello() {
System.out.println("Hello!");
}
}

class User implements Greeting {}

public class Test {
public static void main(String[] args) {
new User().sayHello();
}
}

Question 2

Which statement is correct?

A. Static methods in interfaces can be overridden.
B. Default methods cannot be overridden.
C. Static methods belong to the interface.
D. Default methods must be implemented by classes.

Question 3

What will be the output?

interface MathUtils {
static int square(int x) {
return x * x;
}
}

public class Test {
public static void main(String[] args) {
System.out.println(MathUtils.square(4));
}
}

Share your answers in the comments.

Common Mistakes to Avoid

  • Calling static interface methods using an object reference.
  • Forgetting to use the default keyword.
  • Attempting to override static methods.
  • Ignoring conflicts caused by multiple default methods.
  • Omitting the @Override annotation. (Best practice to use it as it checks whether we correctly override the method)
  • Assuming default methods must always be overridden.

Best Practices

  • Use default methods to extend interfaces without breaking existing implementations.
  • Use static methods for utility or helper functionality.
  • Keep interfaces focused and cohesive.
  • Resolve conflicts explicitly when implementing multiple interfaces.
  • Follow the Interface Segregation Principle (ISP).
  • Use the @Overrride annotation for clarity and maintainability.

If you found this article helpful:

  • Follow for more Java tutorials
  • Share your answers in the comments
  • Save this guide for future reference

Next Article: Understanding Enums in Java with Practical Examples

Thank you!

Have a great day!


Mastering Java Beyond Classes — Part 2: Default and Static Methods in Interfaces was originally published in Javarevisited on Medium, where people are continuing the conversation by highlighting and responding to this story.

This post first appeared on Read More