Rajinder Menu

Default Methods in Java


Interface tutorial Series:




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.

I would like to know your comments and if you liked the article then please share it on social networking buttons.


What is an Interface in Java?


Interface tutorial Series:




An interface is like a class[Link] which has fields and methods but with following difference:

1)All fields in an interface are constants i.e. they are static and final and must be initialized at the time of declaration.

2)Methods do no have bodies in an interface. i.e. methods are abstract except the default and static methods.

Interface is declared using the keyword interface before the interface name as:

interface interface_name {
  ...
}

For example:

interface OurInterface {

 public static final int i=10; //a constant
 public void method1(); //abstract method
 public void method2(); //abstract method

 //default method
 default void method3() {
   System.out.println("This is default method");
 }

 //static method
 static void method4() {
   System.out.println("This is static method");
 }
}

In above interface there is a constant i and it is initialized at the time of declaration. As said earlier fields in an interface are constants and must be initialized, if you do not initialize it it will give error.

All constants in an interface are implicitly public, static and final. So in above interface constant i is
implicitly public, static and final.

All methods in an interface must be abstract except the default and static methods i.e. they do not have have their bodies defined in interface. In above interface method1() and method2() are abstract methods. We do not need to provide keyword abstract they are implicitly abstract. We just do not provide their bodies.

An interface can have default methods and static methods. Default and static methods can have their bodies defined in an interface. They are not abstract.

All constants and methods in an interface are implicitly public. If you provide any other access modifier to them then it will give error. For example

interface OurInterface {

  //this line will give error
  protected int i=10;

  //this line will give error
  protected void method1();

  //this line will give error
  private void method2();

  //this line will give error
  private default void method3() {
    System.out.println("This is default method");
  }

  //this line will give error
  protected static void method4() {
    System.out.println("This is static method");
  }
}

An interface cannot be instantiated i.e. we cannot make objects of an interface by using new operator. For example

OurInterface demo=new OurInterface();

Above line will give error:

Cannot instantiate the type OurInterface


Implementing the interface

Now we have defined an interface but how to use it?

For using an interface we use the concept of inheritance i.e. we implement an interface by making a subclass of it.

For Example


interface OurInterface {

  int i=10;
  void method1();
  void method2();
}

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();
    System.out.println(ourObject.i);
  }
}

Output:

This is method1()
This is method2()
10


In above code OurClass inherits OurInterface by implementing it using keyword implements. Since OurClass inherits OurInterface all the fields and methods of OurInterface are available in OurClass.

I would like to know your comments and if you liked the article then please share it on social networking buttons.


The super Keyword in Java



The super keyword is used to access a field, member or constructor of a superclass from within its subclass.


super and Fields

Consider following example

class Parent{

  String num="ten";
  int i=13;
}

public class Child extends Parent{
  
  int num=10;
  
  public void print() {
   System.out.println("The value of num is:"+num);

  }

  public static void main(String[] args) {
   Child childObject= new Child();
   childObject.print();
  }
}

Output:

The value of num is:10

Here in above code the field num in subclass is hiding the field num in superclass(note that despite that their data types are different).

Now subclass Child has two nums-one is int and one is String(inherited from superclass).

In print() method we have printed the num of subclass. But how to access superclass num in subclass Child?

Here the super keyword comes into play. With the super keyword we can access the superclass variable from within the subclass. For this change the print method in subclass Child as:

public void print() {

  //newly added line
  System.out.println("The value of super.num is:"+super.num);
  System.out.println("The value of num is:"+num);

}

num in above method is representing num of subclass while super.num is representing num of superclass.

If you run above program with changed print() method then output will be:

Output:

The value of super.num is:ten
The value of num is:13

Note that super can access any variable in superclass from within the subclass(except static variables...coming in later section). It is not necessary that superclass variable is a hidden variable like num.

For example to access variable i from subclass change the print() method as:

public void print() {
  //newly added line
  System.out.println("The value of super.num is:"+super.num);
  System.out.println("The value of super.num is:"+super.i);
  System.out.println("The value of num is:"+num);
}

Output:

The value of super.num is:ten
The value of super.i is:13
The value of num is:10


super and Methods

super keyword can also be used for accessing superclass method from within the subclass.

Consider following example

class Parent{

  public void print() {
    System.out.println("This method is in Parent class");
  }

  public void print1() {
    System.out.println("This is another method in Parent class");
  }
}

public class Child extends Parent{

  public void print() {
    System.out.println("This method is in Child class");
  }

  public static void main(String[] args) {

    Child childObject= new Child();
    childObject.print();
  }
}

Output:

This method is in Child class

Now to access print() and print1() method from subclass Child change the print method() in subclass as:

public void print() {

  super.print(); //newly added line
  super.print1(); //newly added line
  System.out.println("This method is in Child class");
}

Output:

This method is in Parent class
This is another method in Parent class
This method is in Child class


super cannot be used in static context

super cannot be called from a static method. For above example you cannot use super keyword in static method main() as:

public static void main(String[] args) {
  
  Child childObject= new Child();
  childObject.print();
  super.print(); //will give error: cannot use super in static context

}

But super can be used to call the static method. For example

class Parent{

  public void print() {
    System.out.println("This method is in Parent class");
  }

  //static method
  public static void print1() {
    System.out.println("This is another method in Parent class");
  }

}


public class Child extends Parent{

  public void print() {
  
    super.print();
    super.print1(); //calling static method
    System.out.println("This method is in Child class");
  }

  public static void main(String[] args) {

    Child childObject= new Child();
    childObject.print();
  }
}

Output:

This method is in Parent class
This is another method in Parent class
This method is in Child class

Similarly super can be used to access static member field also.


super and constructors

We know that constructors[Link] are not members of a class so they are not inherited by subclasses but the constructor of a superclass can be invoked from within the subclass by using super keyword.

For example

class Parent{

  int num;

  //superclass no-arg constructor
  Parent(){
    num=10;
  }
}

public class Child extends Parent{
  
  int i;

  Child(int i){
    super(); //calling superclass no arg constructor
    this.i=i;
  }

  public void print() {
    System.out.println("The value of num is:"+num);
    System.out.println("The value of i is:"+i);
  }

  public static void main(String[] args) {
    
    Child childObject= new Child(13);
    childObject.print();
  }
}

Output:

The value of num is:10
The value of i is:13

In above code super() is used to call the superclass no-argument constructor. This is also known as explicitly calling superclass constructor.

Now consider following example for parametrized superclass constructor[Link]:

class Parent{
  
  int num;
  
  //superclass parameterized constructor
  Parent(int num){
    this.num=num;
  }
}

public class Child extends Parent{

  int i;

  Child(int i,int num){
    super(num); //calling superclass parameterized constructor
    this.i=i;
  }

  public void print() {

    System.out.println("The value of num is:"+num);
    System.out.println("The value of i is:"+i);
  }

  public static void main(String[] args) {

    Child childObject= new Child(13,10);
    childObject.print();
  }
}

Output:

The value of num is:10
The value of i is:13

Here in above code we have used super(num) to call the parameterized superclass constructor

Parent(int num){
 ...
}

I would like to know your comments and if you liked the article then please share it on social networking buttons.