Learn about Interface in Java in depth


Reading time: 35 minutes | Coding time: 10 minutes

In general, you can define an interface as a place, where two systems come together and start interacting with each other. For example, an operating system acts as an interface between the computer and the user or acts as an interface between hardware and other application programs. Likewise in Java, the interface is a mechanism, using which programmers can connect different software components and make them interact with each other. In the following section you will get a clear picture of Java Interface.

You must have learned that, class is a template, which defines an object. Each class definition contains object's attribute as instance variables and object's behavior as instance methods. Have a look at the Student class below.

class Student{
    //rollNumber, name and age are instance variables 
    int rollNumber;
    String name;
    int age;
   
   //instance method definitions
   
    public void setProperties(int rollNumber, String name, int age){
        this.rollNumber = rollNumber;
        this.name = name;
        this.age = age;
    }
    
    public int getRollNumber(){
        return rollNumber;
    }
    
    public String getName(){
        return name;
    }
    
    public int getAge(){
        return age;
    }
}

Here you can see the properties(roll number, name, and age) of Student objects are defined as instance variables inside the Student class. We can set values to these instance variables, which will be different for different student objects. Values set for instance variable determines the state of an object, by which we can differentiate objects of the same type.

Instance methods define the behavior of an object or the operations that can be performed on an object, which may or may not affect the state of an object.
Consider the setProperties instance method from the Student class. Execution of this method will change the object's state, whereas the getAge method will not change the object state, instead we can access the object's age property from the outside world.

You have learned object behaviors are the interactions with the outside world; in Java, these operations are implemented as an instance method. So we can consider the methods, that a class exposes as the interface to the outside world. What happens if we group related methods together and make a standardized interface template? Then this interface can be used in any new class definition, that needs to define the same methods as in the interface. Let's see how we can define an interface.

Defining an Interface

Interface definition consists of modifiers, the keyword interface, interface name, and if the interface extends any parent interfaces then the keyword extends followed by a comma-separated list of parent interfaces and interface body. Syntax and example of an interface definition explained below.

Syntax:

public interface <intrfacename> extends <interface1>, <interface2>, ... , <interfaceN> {
//interface body
} 

Example:

public interface SampleInterFace extends ParentInterface {
    void method1(); //abstract method
    
    default method2(){ //default method
        System.out.println("default method");
    }
    
    static method3(){
        System.out.println("default method"); //static method
    }
    
    int constValue = 1; //constant declaration
}
interface ParentInterface{
    void parentMethod1();
    ...
}
  • If you need to use an interface in any class in any package, you can give public modifier to the package definition. If you omit the public modifier, then the scope of the interface will be limited to the package in which the interface is defined.
  • Convention to interface naming is, interface names should be capitalized like class names.
  • An interface can inherit multiple parent interfaces using the keyword extends.

Interface body

You have already learned that we group related methods together in interfaces. These methods are of three types. abstract methods, static methods and default methods.

abstract methods will not have a method body, or without an implementation given. You can declare the method signature followed by a semicolon.

Unlike abstract methods, static and default methods will have method definitions. static methods define with the keyword static and default methods define with the keyword default.

Since all methods in an interface are public by default, we don't have to explicitly include public modifier with the methods. When an interface is being used by a class all abstract methods need to be implemented by that class.

Interface Implementation

Suppose we are working on a College Management System, where we have different objects like students, tutors, departments, subjects, etc. We have already defined a class Student. Now we are going to define an interface called ContactInfo which will contain method signatures related to contact information.

public interface ContacInfo{
    //Abstract method declarations
    void addAddress(Address address);// Passing object of type Address
    void addEmail(String string);
    void addPhoneNo(long phoneNo);
   
}

Student objects and Tutor objects may need the methods declared in ContactInfo for manipulating contact details. So both classes corresponding to Student and Tutor objects can use ContactInfo interface in their definitions.
Now let's see how this interface is being used in the class Student.

public class Student implements ContactInfo{
    int rollNumber;
    String name;
    int age;
    Address address;
    String email;
    long phoneNo;
    
    public void addAddress(Address address)
    {
        this.address = address;
    }
    
    public void addEmail(String email){
        this.email = email;
    }
    
    public void addPhoneNo(long phoneNo){
        this.phoneNo = phoneNo;
    }
    
}

You can see Student class implemented the interface ContactDetails using the keyword implements. When a class implements an interface, what actually happens is, the class will agree upon a contract with the interface, that the class must implement all abstract methods in the interface. Since all the three methods in ContactDetails are abstract, we have given implementation to all these methods in Student class.

Default Methods

Java 8 has introduced default methods inside interface definition. If we add a new abstract method to an interface, all the implementing class definition will get affected. All those classes need to implement the newly added methods inside them, which will be overhead and some classes might seem additional methods are unnecessary implementations. default methods can handle this situation well, in place of abstract methods. Have a look at the modified ContactInfo interface below.

public interface ContactInfo{
    //abstract methods
    
    ...
        
    //default methods
    default void printAddress(){          //default method
        System.out.println("default method printAddress did not redefine");
    }

}

Unlike abstract methods default methods can have definition inside an interface and default methods start with the keyword default. You can see the definition of default method printAddress inside ContactInfo interface. This method is a new feature addition to ContactInfo and all implementation classes will get access to this newly added method without reimplementing inside them.
For example, we have a class Student which already had implemented the interface ContactInfo and, now take a Student object, try accessing the newly added default method on it.

Student student = new Student();
student.printAddress(); //

This code snippet will print the following

default method printAddress did not redefine

Although there is no implementation of printAddress inside Student class, Student object could access that method, because default methods are available to all the implementation classes. If you want a class-specific implementation of default methods, you can reimplement them like abstract methods, which will override interface-specific definitions.

Have a look at the below sample program, where a class implements two interfaces, and both the interfaces contain the same default method definitions.

public class InterfaceSample implements Interface1, Interface2 {
    
    public static void main(String[] args){
        new InterfaceSample().defaultMethod();
    }
    
    public void method1(){
    }
    
    public void method2(){
    }
    
    public void defaultMethod(){ // redefinition of defaultMethod
        System.out.println("Overridden defaultMethod");
    }
}

interfce Interfce1 {
    
    void method1();
    
    default void defaultMethod(){
        System.out.println("Default method of Interface1");
    }
}

interfce Interfce2 {
    
    void method2();
    
    default void defaultMethod(){
        System.out.println("Default method of Interface2");
    }
}

This program will override the defaultMethod and print the following.

Overridden defaultMethod

If the class InterfaceSample hadn't redefined the common default method, the compiler would have thrown an exception when calling that method on the object; because the compiler can't reason from which interface the default method to choose from since the class has implemented both the interfaces. So redefinition of default method inside implementation class, can avoid the aforementioned compiler ambiguity.

Static Methods

Like default methods, Java 8 has introduced static methods to interfaces.
Similar to the default method, we can add a new feature to an existing interface as static method which will not affect the implementation classes. Unlike default methods, static methods cannot be overridden in the implementation classes, instead, they act as interface-specific methods.
Below the sample program explained the static method concept in detail.

public class Shape implements Operation{

    public static void main(String[] args){
        System.out.println(Operation.getPi()); // accessing interface static method
    }
    
    // abstract method implementations
    ...
}

interface Operation {
    
    //abstract methods
    float findArea();

    float findVolume();

    //static method
    static double getPi() {
        return 3.14;
    }
}

Here static method getPi is just a utility method to access the value of Pi. You must be knowing that class static methods can be accessed using the class name, similarly, we can access interface static methods using interface name.

Constant Declaration

You have already learned that java interface can contain abstract, default and static methods. In addition to methods, an interface can contain constants declarations as well. Let's modify our Operation interface with the constant declaration.

interface Operation {
    
    //abstract methods
    ...
    
    //constant declaration
    double PI = 3.14;

    //static method
    static double getPi() {
        return PI;
    }
}

We have declared a constant PI with value 3.14. You must have noticed one thing here, that static and final modifiers are missing with the constant declaration. Since all constants inside an interface are implicitly public, static, and final we can omit these modifiers.

Interface constants can be used inside interface methods as we used in getPI method. From outside of interface like static methods, we can access constants using interface name.

Interface as Type

Till now you have learned to define and implement interfaces. Another important aspect of the interface is, it can act as a reference type. when defining a new interface, a new reference datatype is being created. A reference datatype can only refer to a memory address. class is a reference datatype, because you can create variables of any class type and can assign memory address of corresponding objects to that variable. Similar to variables of class type, you can create variables of an interface type, but objects assigned to interface type variables must be instances of a class that implemented the interface. But unlike class, you cannot create objects of an interface type, you can only refer objects using interface variable.
Consider the previously defined class Shape which implemented the interface Operation. Variable of type Operation can refer any object of type class Shape.

Shape shape = new Shape();
Operation shapeToOperation = shape;

Untitled-Diagram--6-

We have created a new object of type Shape and given two references to this object; one reference is of type Shape and the other is of type Operaton.
This is an example of polymorphism where an object can take on more than one form. When the object referenced by Shape type we can access all methods of that object using the reference variable. But when the object referenced by the interface type, we can only access interface-specific methods on that object; if we try to access instance methods using interface reference, an exception will be thrown.

Points to Remember

  • An interface definition can contain abstract method signatures, default methods, static methods, and constant definitions.
  • A class can implement more than one interface using the keyword implements.
  • An interface can inherit more than one interface using the keyword extends.
  • All abstract method must be implemented inside implementation classes.
  • static methods cannot be redefined in implementation classes, they can be accessed using interface name.
  • Additional features can be added to interface as default or static methods without affecting the implementation classes.
  • By default all implementation classes will get access to default methods and redefinition is not mandatory.
  • If a class implements two interfaces with same default methods, then redefinition of the default method is preferred to avoid compiler ambiguity in choosing method.
  • Like class, interfce is a reference type; but we cannot create objects of interface type like we create objects of class type.