Java 8 introduced default methods in interfaces, while Java 9 introduced private methods. Both allow method implementations inside interfaces, but they differ in their accessibility, inheritance, overriding, and intended use.
- Default methods provide implementations that implementing classes inherit and may override.
- Private methods provide internal helper logic that is accessible only within the declaring interface and cannot be inherited or overridden by implementing classes.
Default Methods
A default method is an instance method declared with the default keyword in an interface. It contains a method body and provides an implementation for classes that implement the interface. An implementing class inherits the default method unless it overrides it.
interface Vehicle {
default void start() {
System.out.println("Vehicle starts");
}
}
public class GFG implements Vehicle {
public static void main(String[] args) {
GFG obj = new GFG();
obj.start();
}
}
Output
Vehicle starts
Here, start() is a default method. The GFG class inherits the method from Vehicle without providing its own implementation.
How Default Methods Work
When a class implements an interface with a default method, the default implementation is inherited by the class. If the class provides its own implementation, the class method overrides the default method.
- Interface Declaration: The interface defines a method using the default keyword.
- Inheritance: The implementing class inherits the default implementation when it does not define the method.
- Overriding: The implementing class provides its own implementation when different behavior is required.
- Method Execution: The class's overridden method executes when the method is called on its object.
Private Methods
A private method in an interface is an internal method used to share common implementation code between methods declared in the same interface. Private interface methods were introduced in Java 9 and are neither inherited nor overridden by implementing classes or subinterfaces.
interface Vehicle {
default void start(){
check();
System.out.println("Vehicle starts");
}
private void check(){
System.out.println("Checking vehicle");
}
}
public class GFG implements Vehicle{
public static void main(String[] args){
GFG obj = new GFG();
obj.start();
}
}
Output
Checking vehicle Vehicle starts
Here, check() is a private helper method. It is called by the default start() method but is not accessible through the GFG object.
How Private Methods Work
Private methods are defined inside an interface as helper methods for other interface methods. They allow multiple default methods to reuse common implementation logic without exposing the helper method to implementing classes.
- Declaration: The interface declares the helper method using the private keyword.
- Access: The private method is accessible only within the same interface.
- Reuse: Multiple default methods call the same private method when they need common logic.
- Execution: The private method executes when a default method invokes it.
- Encapsulation: Implementing classes cannot directly access or override the private method.
Example: Using Default and Private Methods Together
Private methods are useful when multiple default methods need the same logic. Instead of repeating the same code, the common logic can be placed in a private helper method.
interface Vehicle {
default void start()
{
checkEngine();
System.out.println("Vehicle starts");
}
default void stop()
{
checkEngine();
System.out.println("Vehicle stops");
}
private void checkEngine()
{
System.out.println("Checking engine");
}
}
public class GFG implements Vehicle {
public static void main(String[] args)
{
GFG obj = new GFG();
obj.start();
obj.stop();
}
}
Output
Checking engine Vehicle starts Checking engine Vehicle stops
Here, start() and stop() are default methods inherited by the GFG class. Both methods call the private checkEngine() method to reuse common logic.
- start() and stop() can be called using the GFG object.
- checkEngine() can only be accessed inside the Vehicle interface.
- The private method prevents duplicate code in start() and stop().
- The GFG class cannot access or override checkEngine().
Rules for Default Methods
Default methods were introduced in Java 8 to allow interfaces to provide method implementations. They use the default keyword and can be inherited by implementing classes.
- Must have a body: A default method always provides an implementation inside the interface.
- Implicitly public: Default methods are public and can be accessed through objects of implementing classes.
- Can be inherited: If a class does not override a default method, it automatically inherits the implementation from the interface.
- Can be overridden: An implementing class can provide its own implementation of a default method.
- Cannot be private, protected, or static: A method declared using default is an instance method. Interfaces can have static methods, but they are declared separately without the default keyword.
- Conflicts must be resolved: If two unrelated interfaces provide the same default method, the implementing class must override that method to resolve the conflict.
Rules for Private Interface Methods
Private interface methods were introduced in Java 9. They are mainly used as helper methods to reuse common logic inside an interface.
- Must have an implementation: A private interface method cannot be abstract and therefore must contain a method body.
- Accessible only inside the interface: Implementing classes and subinterfaces cannot directly access private interface methods.
- Cannot be inherited or overridden: Private methods remain internal to the interface in which they are declared.
- Used by instance methods: A private instance method can be called by default methods and other private instance methods within the same interface.
- Private static methods are allowed: A private static method can be used when shared internal logic does not require instance-specific behavior.
Private methods help reduce duplicate code while keeping helper logic hidden from implementing classes.
Default Method Conflict in Java
A default method conflict occurs when a class implements two unrelated interfaces that contain default methods with the same signature.
For example:
interface A {
default void show() {
System.out.println("A");
}
}
interface B {
default void show() {
System.out.println("B");
}
}
public class GFG implements A, B {
@Override
public void show() {
A.super.show();
}
public static void main(String[] args) {
GFG obj = new GFG();
obj.show();
}
}
Output
A
Explanation: A default method conflict occurs when a class implements multiple interfaces that define the same default method. The class must override the method to resolve the ambiguity and can use InterfaceName.super.method() to call a specific interface's implementation.
When to Use Default Methods
Default methods are useful when an interface needs to provide common behavior to its implementing classes.
- Extending existing interfaces: Add new methods without requiring all existing implementing classes to provide an implementation.
- Providing common behavior: Define a common implementation that multiple classes can directly use.
- Allowing customization: Implementing classes can override the default method when different behavior is required.
When to Use Private Methods
Private methods are useful when common logic needs to be reused internally within an interface.
- Reusing common logic: Multiple default methods can call the same private helper method.
- Hiding implementation details: Private methods are accessible only inside the interface.
- Reducing duplicate code: Common operations can be placed in one private method instead of repeating the same code in multiple methods.
Default Methods vs Private Methods
Default and private methods both allow method implementations inside an interface, but they serve different purposes. A default method provides behavior to implementing classes, while a private method is used only for internal code reuse within the interface.
| Feature | Default Method | Private Method |
|---|---|---|
| Introduced in | Java 8 | Java 9 |
| Keyword | default | private |
| Accessibility | Public | Only within the same interface |
| Inherited by implementing class | Yes | No |
| Can be overridden | Yes | No |
| Can be called by implementing class | Yes | No |
| Main purpose | Provides implementation to implementing classes | Provides reusable helper logic inside the interface |