A default method in Java 8 is a special type of method that you can define in an interface. It allows the interface to provide a default implementation (some code) for a method, which means that any class that implements the interface doesn't have to provide its own implementation unless it wants to.
Before Java 8, interfaces in Java could only have abstract methods—methods that didn’t have any code inside them. Any class implementing the interface had to provide code (an implementation) for all the methods in the interface. This caused a problem when Java wanted to update its interfaces.
For example, when Java 8 introduced new features like streams and functional programming, the interfaces in older libraries (like List
or Collection
) needed new methods to support these features. However, adding new methods would break all the existing code that already used those interfaces, because every class that implemented those interfaces would now be required to implement the new methods.
Default methods allow you to add new methods to an interface without breaking the code of existing classes. You provide a default implementation for these methods directly in the interface. Classes that implement the interface can use the default method as it is or override it with their own implementation if they want.
Collections
or Arrays
) were often created to provide helper methods for interfaces. Default methods let you move these helper methods into the interface itself, keeping things more organized.
Imagine you have an interface Vehicle
that has a method start()
that every vehicle (car, bike, etc.) needs to implement. Now, you also want every vehicle to have a stop()
method. Instead of forcing every class to write its own stop()
method, you can provide a default implementation.
interface Vehicle {
void start(); // Every vehicle needs to start differently
// Provide a default stop method
default void stop() {
System.out.println("Vehicle is stopping");
}
}
Now, when a class like Car
implements Vehicle
, it doesn't need to write its own stop()
method unless it wants to. If it doesn't, it will use the default stop()
method from the interface.
class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car is starting");
}
// No need to override stop() unless you want to
}
If you run this:
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.start(); // Outputs: Car is starting
car.stop(); // Outputs: Vehicle is stopping
}
}
If a class implements multiple interfaces that contain default methods with the same signature, the class must override the method to resolve the conflict.
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() {
// Resolve the conflict by explicitly calling one of the interfaces
A.super.show();
}
}
public class Main {
public static void main(String[] args) {
C obj = new C();
obj.show(); // Output: A
}
}