In Java, default methods in interfaces allow you to add new methods to interfaces without breaking the existing implementation of those interfaces. Here's a summary of the rules and behaviors associated with default methods:
Default Method Declaration:
default
keyword in an interface.public interface MyInterface {
default void myMethod() {
// implementation
}
}
Multiple Inheritance:
Inheritance Hierarchy:
interface A {
default void foo() {
System.out.println("A");
}
}
interface B extends A {
default void foo() {
System.out.println("B");
}
}
class C implements B {}
Class vs. Interface:
interface A {
default void foo() {
System.out.println("A");
}
}
class B {
public void foo() {
System.out.println("B");
}
}
class C extends B implements A {}
Abstract Class Implementing Interface:
interface Perishable1 {
default int maxDays() {
return 1;
}
}
interface Perishable2 extends Perishable1 {
default int maxDays() {
return 2;
}
}
class Milk implements Perishable2, Perishable1 {}
public class Test {
public static void main(String[] args) {
Perishable1 obj = new Milk();
System.out.println(obj.maxDays()); // Outputs 2
}
}
Perishable2
extends Perishable1
and overrides maxDays()
. The Milk
class uses the maxDays()
method from Perishable2
.interface A {
default void foo() {
System.out.println("A");
}
}
class B {
public void foo() {
System.out.println("B");
}
}
class C extends B implements A {}
public class Test {
public static void main(String[] args) {
C obj = new C();
obj.foo(); // Outputs "B"
}
}
B
has a method foo()
, which overrides the default method foo()
from interface A
. When C
extends B
and implements A
, the method from class B
takes precedence.interface A {
default void foo() {
System.out.println("A");
}
}
interface B {
default void foo() {
System.out.println("B");
}
}
class C implements A, B {
@Override
public void foo() {
A.super.foo(); // or B.super.foo();
}
}
public class Test {
public static void main(String[] args) {
C obj = new C();
obj.foo(); // Outputs "A" or "B" depending on which super call is used
}
}
C
implements both A
and B
, which have conflicting foo()
methods. C
must override foo()
to resolve the conflict and can use A.super.foo()
or B.super.foo()
to invoke the desired default method.Understanding these rules helps manage default methods in interfaces and resolve conflicts that arise from multiple inheritance. These rules ensure that the behavior of methods is predictable and consistent, allowing interfaces to evolve without breaking existing implementations.