Interface in Java


JavaViews 1335

Interface in Java

Java interface is a keyword that allows us to achieve full abstraction. An interface tells us what it does rather than how it does. This means, an interface contains only function declaration and does not contain function implementation. The class which implements the interface contains the function definition.

Features of Interface in Java

  • Provides full abstraction
  • Contains only function declaration
  • It is similar to classes but cannot instantiate an object or does not have instance variables
  • All variables are public, static and final by default
  • All methods are public and abstract by default
  • Allows to implement multiple inheritance using an interface
  • A class can implement multiple interfaces
  • An interface can extend another interface
  • The implementation class must implement all the methods of the interface.
  • We must initialize all the interface variables during declaration, else it will result in compilation error.
  • Provides more security.

Usage of an Interface

The main purpose of defining an interface is that any class that implements the interface has its own choice to provide the functionality. This means each class that implements the interface can provide different functionality for the same method based on the requirement.

Declaring an Interface

Below is the syntax of declaring an interface.

access interface name {
  type final variable_name;
  returntype method_name(parameter);
}

//Example
public interface Account {
  public void accountdetails();
        public static final int accountnumber;
}

access – we can use either public or default if we do not mention the access type. You can refer to java access modifiers to know more about it.

name – interface name

variable_name – a variable which is by default public, static, and final even if we do not explicitly mention. Since it is final, we cannot change the value in the implementation class.

method_name – method name which contains an empty body(no code) within the method. It is abstract and public by default even if we do not mention it.

Implementing an Interface

Now that we have learned how to declare an interface, next we need to create a class that implements the interface. This means the class needs to provide the functionality or implementation of the method declared in the interface. For this, we use the implements keyword while defining the class. Multiple classes can implement the same interface.

Inside the class, we need to provide the functionality of the method that belongs to the interface. It is mandatory for the class to implement all the methods inside the interface. It can also contain other class-specific methods.

access_type class class_name implements interface_name {
       //provide implementation of the interface method
       returntype method_name(parameter) {
            //code
       }
}

//Example
public class Customer implements Account {
  public void accountdetails() {
    System.out.println("Account details");
  }
}

Now let’s see a simple example of defining an interface and its implementation.

Java Interface Example

This is a simple example of an interface named Shapes that contains a method calculateArea. It is an empty method with no implementation. We then create a class named Square that implements Shapes interface. This class contains the functionality of the method calculateArea that calculates the area of the square.

Since each shape has a different functionality of calculating the area, we have declared Shapes as an interface with the method.

//Interface
interface Shapes {
  public void calculateArea();
}

//Class that implements the interface
class Square implements Shapes {

  int length;
  int area;
  
  Square(int l) {
    this.length = l;
  }
  @Override
  public void calculateArea() {
    area = length * length;
    System.out.println("Area of square is: " + area);
    
  }
}

//Main class
public class MainClass {

  public static void main(String[] args) {
    Square s = new Square(4);
    s.calculateArea();

  }

}
Area of square is: 16

Now, we can see how multiple classes can implement the same interface. So we create another class Rectangle that implements the Shapes interface and contains the code for CalculateArea method to compute the area of a rectangle.

//Interface
interface Shapes {
  public void calculateArea();
}

//Class that implements the interface
class Square implements Shapes {

  int length;
  int area;
  
  Square(int l) {
    this.length = l;
  }
  @Override
  public void calculateArea() {
    area = length * length;
    System.out.println("Area of square is: " + area);
    
  }
}

class Rectangle implements Shapes {
  int length;
  int breadth;
  int area;
  
  Rectangle(int l, int b) {
    this.length = l;
    this.breadth = b;
  }

  @Override
  public void calculateArea() {
    area = length * breadth;
    System.out.println("Area of rectangle is: " + area);
    
  }
  
}

//Main class
public class MainClass {

  public static void main(String[] args) {
    Square s = new Square(4);
    Rectangle r = new Rectangle(4,5);
    s.calculateArea();
    r.calculateArea();

  }

}
Area of square is: 16
Area of rectangle is: 20

Now that we have an idea of interfaces and its implementation, let’s see how to extend an interface. For this, you should have a basic idea of inheritance in java

Extending an Interface

Just like how a class can extend another class to implement inheritance,  an interface can also extend another interface using the keyword extends. In this class, the class that implements the child interface has to provide functionality for all the methods in the child and parent interfaces.

You will be able to understand clearly with an example below.

We have defined 2 interfaces Bank and Account. The Bank interface has a string variable and a method. The Account interface has a method. This interface extends the Bank interface which means it inherits the Bank interface methods and variables.

Now, we create a Customer class that implements the Account interface. Since the Account interface extends the Bank interface, the Customer class has to implement all the methods of both the interfaces. Else it will result in a compilation error. The variable in the Bank interface is by default final, which means we cannot change its value in the implementation class.

interface Bank {
  String ifsccode = "HDFC00004680";
  public void displayCustomerDetails();
}

interface Account extends Bank{
  public void displayAccountDetails();
}

class Customer implements Account {
  
  String customername;
  int accountnumber;
  Customer(String name, int no) {
    this.customername = name;
    this.accountnumber = no;
  }

  @Override
  public void displayCustomerDetails() {
    System.out.println("Customer Details");
    System.out.println("Customer Name: " + customername);
    
  }

  @Override
  public void displayAccountDetails() {
    System.out.println("Account Details");
    System.out.println("IFSC Code: " + ifsccode);
    System.out.println("Account number: " + accountnumber);
  }
  
}
public class MultipleInterface {

  public static void main(String[] args) {
    Customer c = new Customer("Raju", 456712345);
    c.displayCustomerDetails();
    c.displayAccountDetails();

  }

}
Customer Details
Customer Name: Raju
Account Details
IFSC Code: HDFC00004680
Account number: 456712345

Implementing Multiple Inheritance

Java does not support multiple inheritance concept, which means inheriting properties and methods of multiple classes. This is because of the ambiguity that arises when multiple classes have the same method name. But we can implement multiple inheritance using Java interface which does not show any ambiguity. This is because the class that implements the interface provides the method functionality. To implement multiple interfaces, we need to specify the interface names separated by a comma in class definition.

Example

We have 2 separate interfaces Account, Deposit. Both the interfaces have 2 methods each where 1 method printdetails is common to both the interfaces. Now we create a class Customer that implements both the interfaces. This class has to provide the functionality of all the methods defined in both the interfaces. Since 1 method is common, only 1 implementation is required.

interface Account {
  public void accountdetails();
  public void printdetails();
}
interface Deposit {
  public void depositdetails();
  public void printdetails();
}
public class Customer implements Account,Deposit {
  public void accountdetails() {
    System.out.println("Account details");
  }
  public void depositdetails() {
    System.out.println("Deposit Details");
  }

  public void printdetails() {
    System.out.println("Printing");
  }
  public static void main(String[] args) {
    Customer c = new Customer();
    c.accountdetails();
    c.depositdetails();
    c.printdetails();
  }

}
Account details
Deposit Details
Printing

There is an important point to note. A class cannot implement a method that has the same method name but different return types. In this case, it will result in a compilation error.

interface A {
  public String display();
}

interface B {
  public void display();
}

class Sample implements A, B {

  public String display() { //This will show error
        
  }
  
  public void display() { //This will show error
    
  }
  
}

Default method in Interface

Generally methods inside an interface are public and abstract. From Java 8, we can also decalre a default method. The main use of this is, suppose we want to add a new method to an interface, then we must include its implementation in all the classes that implements the interface. This might be very difficult. Hence Java 8 introduced default methods so that we can directly declare it within the interface along with the functionality. We can access the default method using the class reference object similar to inheritance.

interface demo {
  public void show();
  default void display() {
    System.out.println("New method");
  }
}

public class DefaultDemo implements demo{

  @Override
  public void show() {
    System.out.println("Existing method");
  }
  
  public static void main(String[] args) {
    DefaultDemo d = new DefaultDemo();
    d.show();
    d.display();
  }

}
Existing method
New method

Variable name conflicts in Java Interface

Now, consider an example where we have the same variable name both the interfaces. In this case, we can access these variables from the implementation class through the interface reference as below. To access the interface A variable we use A.name and for B interface variable, we use B.name. This resolves the ambiguity when we access the variable name alone. Hence it throws an error when we use the variable name without any interface reference.

interface A {
  String name = "Interface A";
}

interface B {
  String name = "Interface B";
}

class Sample implements A, B {
  public void display() {
    //System.out.println(name); //error
    System.out.println(A.name);
    System.out.println(B.name);
    
  }
  
}
public class MultipleInheritance {

  public static void main(String[] args) {
    Sample s = new Sample();
    s.display();

  }

}
Interface A
Interface B

Tag or Marker Interface

When we define an empty interface, we call it a tag or marker interface. This type of java interface does not have any properties or methods. Few existing tag interfaces in java are EventListener, Serializable, Remote(java.rmi.Remote). The main use of tag interface is that when the class implements such an interface, it can use the membership of that interface. This means the JVM (Java Virtual Machine) performs a special operation to support that interface. For example, serialization or deserialization process.

A tag interface looks like the below. This java interface is mainly used for JVM.

package java.uti;
public interface EventListener 
{ }

Nested Interface

When we create an interface within another interface, we call it a nested interface or an inner interface. One best example is the Entry interface. This is defined inside the Map interface. This is why we access it using Map.Entry and cannot access the Entry interface directly.

The main use of the nested interface is it allows to implement only a particular interface within a grouped interface. We can always access the inner interface only by using the outer interface. By default, nested interfaces are static and public. However, we can change the access type of the inner interface.

We can declare a nested interface in 2 different ways.

  • Inside  another interface
  • Inside a class.

Example of an inner interface within an interface

In the below example, we have 2 interfaces X and Y with methods display() and print(). If we want to implement the inner interface Y, we must mention it as X.Y in the class definition. Hence Main class implements the Y interface method print, and the Outer class implements the X interface method display.

interface X {
  public void display();
  interface Y {
    public void print();
  }
}

class Main implements X.Y {

  public void print() {
    System.out.println("Y interface Print method");
    
  }
}

class Outer implements X {

  @Override
  public void display() {
    System.out.println("X interface display method");
    
  }
}

public class NestedInterfaceDemo {

  public static void main(String[] args) {
    Main m = new Main();
    m.print();
    Outer o = new Outer();
    o.display();
  }

}
Y interface Print method
X interface display method

Example of an Interface within a class

We can also define an interface within a class as you can see in the below example. In this case, the implementation class has to implemnet the interface as DisplayInterface.sample which means you can access the inner interface only using its class name. Both the class and interface can have the same method since different classes implement it. Hence there will not be any ambiguity.

class DisplayInterface {
  interface sample {
    public void show();
  }
  
  //class method
  public void show() {
    System.out.println("DisplayInterface Class show method");
  }
}

public class InnerInterfaceDemo implements DisplayInterface.sample {

  @Override
  //Interface method
  public void show() {
    System.out.println("Sample interface show method");
    
  }
  
  public static void main(String[] args) {
    InnerInterfaceDemo i = new InnerInterfaceDemo();
    i.show();
    DisplayInterface d = new DisplayInterface();
    d.show();
  }
}
Sample interface show method
DisplayInterface Class show method

Reference

Translate »