Interface in Java (OOP)

What is an Interface?

The word “interface” means a medium or means of communication between two entities. Similarly, in Java, interfaces are used to ease the communication between various classes.

In Java, an interface looks similar to any class and contains only constants, method signatures, default methods, and static methods. Before going into the implementation and uses of interfaces, first, let us understand why we need them.

Why do we need interfaces?

Many times, separate groups of developers have to agree to a basic reference about how their software interacts. Ideally, each group should be able to write their code without knowing the other group’s code. This is where interfaces come into play in defining such contracts.

For example, assume that cars are driven by software (quite true these days). Now, the automobile manufacturers write software to operate any car consisting of operations like — stop, turn left, turn right, start, etc. Now, you know Machine learning, by which you have written algorithms for a self-driving car, but to make the car drive, you must know how to make the car stop, turn in either direction, start, etc. 

So there is a need for a common interface between the two groups (manufacturers and driving unit). The manufacturers must provide this interface that spells out what methods can be invoked to operate the car. The driving unit then writes software using the interface methods according to their needs. This way, neither group needs to know how another group is writing its code.

The basic needs that an interface fulfills are complete abstraction by using abstract methods; it also helps in achieving multiple inheritance in Java (by extending interfaces) and defining a prototype of properties of a family of classes which ensures loose coupling.

Now let’s study interfaces technically.

Defining an Interface

An interface declaration consists of an access modifier, interface keyword, name of the interface, list of parent interfaces (comma separated if any exists), and the body.

Syntax:

public interface NameInterface extends Interface1, Interface2 {
    //constants
    //method signatures
    //rest body...
}

Note: The part in bold involves inheritance; you can refer to the basics of inheritance here.

  • An interface can only extend interfaces and can not implement an interface.
  • A very important feature of an interface in Java is that it can extend several other interfaces in spite that a general class can extend only one other class.

The body

The body can contain abstract, default, static methods, and constants. An abstract method does not have a definition, default and static methods are declared with default and static keywords respectively, and both have definitions. All methods in an interface are implicitly public. All constants in an interface are implicitly public, static, and final.

Writing the Interface

The interface written by the manufacturing unit of our self-driving car may look like this:

public interface Controls {
    //constants
    int maxSpeed = 210;
    //abstract methods
    int turnLeft(int distance);
    int turnRight(int distance);
    int accelerate (int distance, int toSpeed);
    int brake(int distance, int toSpeed);
     
    //default methods
    default void stop(int distance){
        System.out.println("STOP!");
    }
    //rest part of the interface
}

Implementing the Interface

Now that we have the interface given by the manufacturing team, the driving team will implement it as per their need. By implementing an interface, we mean to define classes with an implements clause followed by the name of interfaces they implementand provide suitable definitions to the abstract methods of the interface.

Syntax:

public class Driving implements Controls{
    //methods and variables of the Driving class...
    //giving definition to abstract methods of Controls
       
    public int turnLeft(int distance){
        //some code
    }
    public int turnRight(int distance){
        //some code
    }
    //other definitions...
}

Note: 

  • “implements” is a keyword
  • The implementing class can also extend to another class. In such a case, the implements clause follows the extends clause. 

That’s it! Both the driving and manufacturing teams could write their code with great ease and without depending on each other, thanks to Java interfaces.

Using Interfaces as a Reference Type

An interface is a reference type, which means we can use it as a reference data type just like any other class. But, a reference of interface type must be assigned with an instance of a class that implements that interface.

Consider this example :

public interface Animal {
    void sound();
}

public class Dog implements Animal{
    public void name(){
        System.out.println("JIMMY");
    }
    //implementing method sound()
    public void sound(){
        System.out.println("BARK");
    }
}

public class Man{
    //class body...
}

public class Test {
    public static final void main(String[] args) {
        Animal animal = new Dog();
        animal = new Man();
    }
}

The bold phase line generates an error because the Man class does not implement the Animal interface; hence the Animal reference type can not reference it. Also, think, a man is not an animal, right? Now, consider this main method:

public static final void main(String[] args) {
    Animal animal = new Dog();
    animal.sound(); 
    animal.name();
}

The bold phase line is erroneous because the reference variable is of Animal type, and the Animal interface does not have the name() method. However, the sound method will print “BARK” of the instance of Dog class.

To use the name() method, we have to use the reference of Dog type, that is :

public static final void main(String[] args) {
    Animal animal = new Dog();
    animal.sound();
    Dog dog = (Dog)(animal);
    dog.name();
    dog.sound();
}

//alternatively we can write ((Dog)animal).name();
//The bold phase lines involves typecasting.

Updating Interfaces

Imagine that in the future, the manufacturing team of the self-driving car has to add some features to their interface. If they add those features to the existing interface, then all the classes that implement it will break, and the clients will be unhappy.

One alternative is that the manufacturing team creates a new interface that will extend the existing interface, and the users will have to upgrade to this new interface.

Alternatively, the features can be added as default methods to the interface because the default methods allow us to add new functionalities to the interface and ensure binary compatibility with code written for the existing interface.

Pros of Interfaces

  1. An interface mainly consists of abstract methods; hence it allows total abstraction by hiding the implementation of these methods from its clients.
  2. Interfaces allow us to implement the concept of multiple inheritance in java because a class can implement a number of interfaces but can extend a single class only.
  3. Interfaces ensure loose coupling. First, let’s understand loose coupling. Coupling refers to the degree of dependence between two different classes. Tight coupling occurs when a dependent class contains a reference to a concrete class. If the concrete class is edited, the dependent class will break and need to be edited too. Loose coupling occurs when a change in a concrete class doesn’t affect any code in the dependent class. This is possible if the dependent class contains a reference to an interface, which can then be implemented by one/many concrete classes. It is necessary to list all the possible methods in the interface so that we don’t have to edit the interface in the future. Thus the concrete class and the dependent class are loosely coupled.

Enjoy learning. Enjoy OOPS!

More From EnjoyAlgorithms

Our weekly newsletter

Subscribe to get free weekly content on data structure and algorithms, machine learning, system design, oops design and mathematics.

Follow Us:

LinkedinMedium

© 2020 EnjoyAlgorithms Inc.

All rights reserved.