Java Default Methods in Interfaces: Enhancing Flexibility and Backward Compatibility
Discover the significance of default methods in Java interfaces introduced in Java 8. Learn how default implementations allow for backward compatibility while enabling new functionalities like lambda expressions. Understand how default methods enhance existing interfaces, such as List
and Collection
, without breaking current implementations.
Java - Default Methods in Interfaces
Java Default Methods Overview
Java introduced default method implementation in interfaces with Java 8. Before Java 8, interfaces could only contain abstract methods. This feature was added for backward compatibility, allowing older interfaces to utilize lambda expressions.
For instance, the List
or Collection
interfaces lacked a forEach
method declaration, and adding such a method would break existing implementations. Default methods enable the List
and Collection
interfaces to include a default implementation of the forEach
method without requiring implementing classes to define it.
Syntax
The following is the syntax for defining a default method in an interface in Java:
Syntax
public interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
Learn Java in-depth with real-world projects through our Java certification course. Enroll to become a certified expert and boost your career.
Java Default Method Example
Below is an example demonstrating the use of default methods in interfaces:
Tester Class Implementation
package com.tutorialsarena;
interface Vehicle {
// default method must have an implementation
default void print() {
System.out.println("I am a vehicle!");
}
}
// The implementing class does not need to implement the default method
public class Tester implements Vehicle {
public static void main(String args[]) {
Tester tester = new Tester();
// The implementing class can access the default method as its own
tester.print();
}
}
Output
Output
I am a vehicle!
Default Methods in Multiple Inheritance
When using default methods in interfaces, a class may implement two interfaces that contain the same default method, leading to ambiguity. The following example illustrates how to resolve this issue:
Ambiguity Resolution Example
public interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
public interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
// Solution: Create an own method that overrides the default implementation
public class Car implements Vehicle, FourWheeler {
public void print() {
System.out.println("I am a four wheeler car vehicle!");
}
}
After overriding the default method with your own implementation, you can use the print
method from the Car
class as follows:
Tester Class with Car Implementation
package com.tutorialsarena;
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
// Overriding the default method resolves the ambiguity
public void print() {
System.out.println("I am a four wheeler car vehicle!");
}
}
public class Tester {
public static void main(String args[]) {
Car car = new Car();
car.print();
}
}
Output
Output
I am a four wheeler car vehicle!
Calling Default Methods of Interfaces
Another way to resolve the ambiguity is to call the default method of a specified interface using super
:
Calling Default Method Example
public class Car implements Vehicle, FourWheeler {
public void print() {
// Call the default method from the Vehicle interface
Vehicle.super.print();
}
}
Example: Calling Default Method
In this example, the Car
class implements two interfaces, and it can call the default method from either interface:
Tester Class with Super Call
package com.tutorialsarena;
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
// Use the default method of an interface
public void print() {
FourWheeler.super.print();
}
}
public class Tester {
public static void main(String args[]) {
Car car = new Car();
car.print();
}
}
Output
Output
I am a four wheeler!
Static Default Methods in Java
Java 8 also allows interfaces to have static default methods, which act as helper or utility functions. These methods help encapsulate code better:
Static Default Method Example
public interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
static void blowHorn() {
System.out.println("Blowing horn!!!");
}
}
Example: Calling Static Default Method of Interface
Below is an example where we call the static method directly:
Tester Class with Static Method Call
package com.tutorialsarena;
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
static void blowHorn() {
System.out.println("Blowing horn!!!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
public void print() {
// Call the Vehicle interface default print method
Vehicle.super.print();
FourWheeler.super.print();
// Call the static method from the Vehicle interface
Vehicle.blowHorn();
System.out.println("I am a car!");
}
}
public class Tester {
public static void main(String args[]) {
Vehicle vehicle = new Car();
vehicle.print();
// Call the Vehicle interface static blowHorn method
Vehicle.blowHorn();
}
}
Output
Output
I am a vehicle!
I am a four wheeler!
Blowing horn!!!
I am a car!
Blowing horn!!!