Java 8 brought the introduction of default methods in the Java programming language. Default methods are methods specified within an interface with a concrete implementation, enabling the direct definition of method bodies within interfaces. Unlike abstract methods, default methods are non-abstract in nature.
Before Java 8, interfaces could only contain abstract methods. This required implementing classes to define the method's implementation.
Default methods are declared by using the keyword "default" before the method's return type.
default return_type defaultMethodName() {
//method body
}
Why Default Methods?
Prior to Java 8:
- Interfaces were limited to containing only abstract methods.
- Introducing a new method necessitated each implementing class to implement it, causing backward compatibility issues.
Utilizing Default Methods:
- Interfaces can be enhanced with additional functionality.
- Implementing classes are not obligated to implement the new method unless they desire to replace it.
Example: Default Method
Example
interface MyInterface {
void greet(); // abstract method
default void sayHello() { //default method with method body
System.out.println("Hello from default method!");
}
}
class MyClass implements MyInterface {
//implementation of abstract method
public void greet() {
System.out.println("Greetings!");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.greet(); // invoking abstract method
obj.sayHello(); //invoking default method
}
}
Output:
Greetings!
Hello from default method!
Multiple Inheritance Conflict
In situations where a class implements two interfaces containing an identical default method, it becomes necessary to provide an overriding implementation of that method to eliminate any ambiguity. Take, for instance, the program provided below.
interface A {
default void show() {
System.out.println("A's default");
}
}
interface B {
default void show() {
System.out.println("B's default");
}
}
class C implements A, B {
public void show() {
A.super.show(); // or B.super.show()
}
}
Within the program mentioned earlier, two interfaces, namely A and B, have been established. Each interface incorporates the show default method. The primary class C executes both interfaces A and B, resulting in a method ambiguity scenario due to Java's inability to determine which show method to inherit.
In order to clarify this uncertainty, C can address the ambiguity by overriding the show method and explicitly invoking one of the versions from the super-interface using A.super.show or B.super.show.
When the method show is called using A.super.show, the output will be the default value of A. Conversely, invoking B.super.show will result in the default value of B being output.
Characteristics of Default Method
When implementing classes, developers have the option to either utilize the default implementation or override it with their custom behavior.
Inheritance of Behavior from Multiple Sources: Default methods enable a type of inheritance of behavior from multiple sources, as a class has the capability to adopt various interfaces, each possibly including default methods. This stands in contrast to the conventional class inheritance, which restricts inheritance to a single source.
Dealing with Conflict: In scenarios where a class adopts numerous interfaces containing default methods sharing identical signatures (known as the "Diamond Problem"), the class in question needs to precisely redefine the conflicting method to eliminate any uncertainty. Another approach is to directly invoke a particular interface's default method by utilizing InterfaceName.super.methodName.
Support for backward compatibility allows new methods to be added to current interfaces without requiring immediate implementation from all classes that implement them, thereby avoiding disruption of existing codebases.
An instance of a default method in Java 8 is the forEach method, which was introduced to the Iterable interface.
Encouraging Code Reusability: Interfaces enable the provision of a standard behavior for methods, minimizing the repetition of code in classes that would otherwise need to implement the same basic functionality.
Static Methods inside Java 8 Interface
It is also possible to declare static methods within an interface, which are typically utilized for defining utility methods.
The upcoming illustration provides a demonstration of how to incorporate a static method within an interface.
Example
interface Sayable {
// default method
default void say() {
System.out.println("Hello, this is default method.");
}
// Abstract method
void sayMore(String msg);
// static method
static void sayLouder(String msg) {
System.out.println(msg);
}
}
public class Main implements Sayable {
public void sayMore(String msg) { // implementing abstract method
System.out.println(msg);
}
public static void main(String[] args) {
Main dm = new Main();
dm.say(); // calling default method
dm.sayMore("This is abstract method."); // calling abstract method
Sayable.sayLouder("This is static method."); // calling static method
}
}
Output:
Hello, this is default method.
This is abstract method.
This is static method.
Abstract Class Vs. Java 8 Interface
Following the inclusion of default and static methods within an interface, the necessity of an abstract class in Java comes to mind. While an interface and an abstract class share similarities, one key distinction is the ability to establish constructors in the abstract class, a capability lacking in interfaces. To illustrate, let's examine the subsequent program.
Example
abstract class AbstractClass {
public AbstractClass() { // constructor
System.out.println("You can create constructor in abstract class");
}
abstract int add(int a, int b); // abstract method
int subtraction(int a, int b) { // non-abstract method
return a - b;
}
static int multiply(int a, int b) { // static method
return a * b;
}
}
public class Main extends AbstractClass {
public int add(int a, int b) { // implementing abstract method
return a + b;
}
public static void main(String[] args) {
Main a = new Main();
int result1 = a.add(20, 10); // calling abstract method
int result2 = a.subtraction(20, 10); // calling non-abstract method
int result3 = AbstractClass.multiply(20, 10); // calling static method
System.out.println("Addition: " + result1);
System.out.println("Subtraction: " + result2);
System.out.println("Multiplication: " + result3);
}
}
Output:
You can create constructor in abstract class
Addition: 30
Subtraction: 10
Multiplication: 200
Java Default Method MCQs
- Which of the following statements about default methods in interfaces is correct?
- A default method must be overridden in all implementing classes.
- A default method can have a body and may or may not be overridden in implementing classes.
- Default methods cannot exist in interfaces.
- A default method must be abstract.
Introduced in the Java 8 version, default methods are methods in interfaces that can include an implementation. Unlike abstract methods, default methods do not require overriding unless the implementing class needs to define specific behavior.
interface Sayable {
default void say() {
System.out.println("Default Method");
}
}
public class Test implements Sayable {
public static void main(String[] args) {
new Test().say();
}
}
- Compilation Error
- Runtime Error
- No output
- Default Method
Explanation: The interface Sayable has a default method say, which is inherited by the class Test. So, Test can call say and it will print Default Method.
- Which keyword is used to define a method with a default implementation in an interface in Java 8?
- static
- final
- abstract
- default
Explanation: In Java 8, the default keyword is used in interfaces to define methods with a body, allowing backward compatibility for interface changes.
- Which of the following is true about static methods in Java interfaces?
- They can be called using object reference.
- They can be inherited by implementing classes.
- They must be called using the interface name.
- They cannot be defined inside interfaces.
Explanation: Static methods inside interfaces are not inherited and must be called using the interface name, like InterfaceName.method.
- Which of the following is not possible in Java interfaces?
- Abstract methods
- Static methods
- Constructors
- Default methods
In Java, constructors are not allowed in interfaces due to the inability to instantiate interfaces directly. However, interfaces can contain abstract, static, and default methods.