Interface tutorial Series:
- What is an Interface in Java
- Default Methods in Java
- Static method in Interface
We know that methods in an interface do not have method bodies. They are abstract methods. But introducing in Java SE8 methods in an interface can have bodies. But in order to have a body in an interface a method need to be declared default by using default keyword. For example:
interface OurInterface {
public void method1(); //abstract method
public void method2(); //abstract method
//default method
default void method3() {
System.out.println("This is default method");
}
}
In above code method1() and method2() are abstract methods but method3() is not. The method3() is a default method declared by using keyword default. It can have method body as defined in the above interface.
A class implementing such interface needs only to define abstract methods i.e. that class has to provide bodies only for abstract methods. It need not to provide body for default method. Default method gets inherited in such class along with its definition or body. For example
interface OurInterface {
public void method1(); //abstract method
public void method2(); //abstract method
//default method
default void method3() {
System.out.println("This is default method");
}
}
public class OurClass implements OurInterface{
//Implementing an abstract method1()
public void method1(){
System.out.println("This is method1()");
}
//Implementing an abstract method2()
public void method2(){
System.out.println("This is method2()");
}
public static void main(String s[]) {
OurClass ourObject=new OurClass();
ourObject.method1();
ourObject.method2();
ourObject.method3(); //calling default method; body inherited //from interface
}
}
Output:
This is method1()
This is method2()
This is default method
10
In above code OurClass implements the OurInterface. So it inherits the default method3() automatically.
Why we use default methods:
Suppose there are three classes namely OurFirstClass, OurSecondClass and OurThirdClass which implements OurInterface.
interface OurInterface {
public void method1(); //abstract method
}
public class OurFirstClass implements OurInterface{
//Implementing an abstract method1()
public void method1(){
System.out.println("OurFirstClass :This is method1()");
}
public static void main(String s[]) {
OurClass ourObject=new OurClass();
ourObject.method1();
}
}
public class OurSecondClass implements OurInterface{
//Implementing an abstract method1()
public void method1(){
System.out.println("OurSecondClass :This is method1()");
}
public static void main(String s[]) {
OurClass ourObject=new OurClass();
ourObject.method1();
}
}
public class OurThirdClass implements OurInterface{
//Implementing an abstract method1()
public void method1(){
System.out.println("OurThirdClass:This is method1()");
}
public static void main(String s[]) {
OurClass ourObject=new OurClass();
ourObject.method1();
}
}
Now suppose there is a requirement and we have to change our interface by adding two more methods namely method2() and method3() as:
interface OurInterface {
public void method1(); //abstract method
public void method2(); //New abstract method added
public void method3(); //New abstract method added
}
Now as a class which implements an interface has to implement all abstract methods of that interface so in our case here all three classes have to provide bodies for these two newly added methods. In other words we will say that because our interface has changed so it has broken our classes. Now if such subclasses are more in number in a big project then it is not advisable to change all those subclasses.
Here default method comes into play.
Instead of changing all our subclasses we will declare method2() and method3() as default method in interface OurInterface. As default methods can have their bodies in interface we need to provide their definitions/bodies only in interface instead of all three subclasses. And that bodies will get inherited in those subclasses. We need not to implement these two new methods in all three subclasses.
interface OurInterface {
void method1();
default void method2() {
System.out.println("This is default method");
}
default void method3() {
System.out.println("This is another default method");
}
}
public class OurFirstClass implements OurInterface{
//Implementing an abstract method1()
public void method1(){
System.out.println("OurFirstClass :This is method1()");
}
public static void main(String s[]) {
OurClass ourObject=new OurClass();
ourObject.method1();
ourObject.method2(); //method body inherited from interface
ourObject.method3(); //method body inherited from interface
}
}
Output:
OurFirstClass :This is method1()
This is default method
This is another default method
OurFirstClass need not to provide body for method2() and method3(). Their bodies will get inherited from interface because they are declared as default methods. Similarly with OurSecondClass and OurThirdClass.
Default Methods and Overriding
Now suppose there is a default method present in an interface and the implementing class also provides the body of that default method in its definition. For example
interface OurInterface {
void method1();
default void method2() {
System.out.println("This is default method");
}
}
public class OurFirstClass implements OurInterface{
//Implementing an abstract method1()
public void method1(){
System.out.println("OurFirstClass :This is method1()");
}
//defining default method again in implementing class
void method2() {
System.out.println("Overriding default method2()");
}
public static void main(String s[]) {
OurClass ourObject=new OurClass();
ourObject.method1();
ourObject.method2(); //will call overrided method present in //OurFirstClass
}
}
Output:
OurFirstClass :This is method1()
Overriding default method2()
Here we will say that method2() in implementing class has overrided the default method present in interface. When we call the method2() the overrided version of method2() present in implementing class will be called instead of the version present in interface.