Until Java 1.7, inside an interface, we could only define public abstract methods and public static final variables. Every method present inside an interface is always public and abstract, whether we declare it or not. Similarly, every variable declared inside an interface is always public, static, and final, whether we declare it or not. With the introduction of default methods in interfaces, it is now possible to include method implementations within interfaces, providing more flexibility and enabling new design patterns.
From Java 1.8 onwards, in addition to these, we can declare default concrete methods inside interfaces, also known as defender methods.
We can declare a default method using the keyword default
as follows:
Interface default methods are by default available to all implementation classes. Based on the requirement, an implementation class can use these default methods directly or override them.
Default Methods in Interfaces Example:
Default methods are also known as defender methods or virtual extension methods. The main advantage of default methods is that we can add new functionality to the interface without affecting the implementation classes (backward compatibility).
Note: We can’t override Object class methods as default methods inside an interface; otherwise, we get a compile-time error.
Example:
Compile-Time Error: The reason is that Object class methods are by default available to every Java class, so it’s not required to bring them through default methods.
Default Method vs Multiple Inheritance
Two interfaces can contain default methods with the same signature, which may cause an ambiguity problem (diamond problem) in the implementation class. To overcome this problem, we must override the default method in the implementation class; otherwise, we get a compile-time error.
Example 1:
Example 2:
Differences between Interface with Default Methods and Abstract Class
Even though we can add concrete methods in the form of default methods to the interface, it won’t be equal to an abstract class.
Interface with Default Methods | Abstract Class |
Every variable is always public static final. | May contain instance variables required by child classes. |
Does not talk about the state of the object. | Can talk about the state of the object. |
Cannot declare constructors. | Can declare constructors. |
Cannot declare instance and static blocks. | Can declare instance and static blocks. |
Functional interface with default methods can refer to lambda expressions. | Cannot refer to lambda expressions. |
Cannot override Object class methods. | Can override Object class methods. |
Static Methods in Java 8 Inside Interface
From Java 1.8 onwards, we can write static methods inside an interface to define utility functions. Interface static methods are by default not available to the implementation classes. Therefore, we cannot call interface static methods using an implementation class reference. We should call interface static methods using the interface name.
As interface static methods are not available to the implementation class, the concept of overriding is not applicable. We can define exactly the same method in the implementation class, but it’s not considered overriding.
Example 1:
Example 2:
This is valid but not considered overriding.
Example 3:
This is valid but not considered overriding.
From Java 1.8 onwards, we can write the main()
method inside an interface, and hence we can run the interface directly from the command prompt.
Example:
At the command prompt:
Differences between Interface with Default Methods and Abstract Class
In conclusion, while interfaces with default methods offer some of the functionalities of abstract classes, there are still distinct differences between the two, particularly in terms of handling state, constructors, and method overriding capabilities.
Static Methods Inside Interface
It is important to note that interface static methods cannot be overridden. Here is another example illustrating this concept:
Example:
In this example, CalculationInterface.calculate()
and CalculationClass.calculate()
are two separate methods, and neither overrides the other.
Main Method in Interface
From Java 1.8 onwards, we can write a main()
method inside an interface and run the interface directly from the command prompt. This feature can be useful for testing purposes.
Differences between Interface with Default Methods and Abstract Class (Continued)
In conclusion, while interfaces with default methods offer some of the functionalities of abstract classes, there are still distinct differences between the two, particularly in terms of handling state, constructors, and method overriding capabilities.
Static Methods Inside Interface (Continued)
It is important to note that interface static methods cannot be overridden. Here is another example illustrating this concept:
Example:
In this example, CalculationInterface.calculate()
and CalculationClass.calculate()
are two separate methods, and neither overrides the other.
Main Method in Interface
From Java 1.8 onwards, we can write a main()
method inside an interface and run the interface directly from the command prompt. This feature can be useful for testing purposes.
Example:
To compile and run the above code from the command prompt:
Additional Points to Consider
- Multiple Inheritance in Interfaces:
- Interfaces in Java support multiple inheritance, which means a class can implement multiple interfaces. This is particularly useful when you want to design a class that conforms to multiple contracts.
- Resolution of Default Methods:
- If a class implements multiple interfaces with conflicting default methods, the compiler will throw an error, and the class must provide an implementation for the conflicting methods to resolve the ambiguity.
Example:
3. Functional Interfaces with Default Methods:
- A functional interface is an interface with a single abstract method, but it can still have multiple default methods. This combination allows you to provide a default behavior while still adhering to the functional programming paradigm.
Summary
Java 8 introduced significant enhancements to interfaces, primarily through the addition of default and static methods. These changes allow for more flexible and backward-compatible API design. Here are the key points:
- Default Methods: Provide concrete implementations in interfaces without affecting existing implementing classes.
- Static Methods: Allow utility methods to be defined within interfaces.
- Main Method in Interfaces: Enables testing and execution of interfaces directly.
- Conflict Resolution: Requires explicit resolution of conflicting default methods from multiple interfaces.
- Functional Interfaces: Can have default methods alongside a single abstract method, enhancing their utility in functional programming.
These features make Java interfaces more powerful and versatile, facilitating more robust and maintainable code design.
