Interface in Java

What is an interface in Java?

The basic role of the interface in Java is to define a set of methods that can be implemented in other classes.

There can be multiple classes that implement the same interface. Then, in run-time, using the reference type of the given interface (polymorphism) will be determined which method will be called.

A class can inherit the properties and behaviours of another class, but, in Java, only single inheritance is possible, which means that a class can only have one superclass.

However, sometimes it is necessary to combine behaviours from two or more classes to achieve the desired functionality.

Considering that only single inheritance is used in Java, the problem of the hierarchy of classes with mixed behaviour is solved using the interface.

Classes inherit the interface using the keyword implements.

Example of declaring an interface in Java:

interface Runnable {}


Example of using the interface:

interface Vehicle {
  void move();
}

class Car implements Vehicle {
    
  @Override
  public void move() {
    System.out.println("The car is moving...");
  }
}

class Test {
    
  public static void main(String[] args) {
    Vehicle car = new Car();
    car.move();
  }
}
Output: The car is moving…

Examples and notes

An interface cannot be instantiated just like an abstract class:

interface Vehicle {
  void move();
}

class Test {
  
  public static void main(String[] args) {
    Vehicle car = new Vehicle(); // DOES NOT COMPILE
  }
}

Before Java 8, interfaces could only contain fields and abstract methods. Since Java 8 and Java 9, we can have defaultprivate and static methods in an interface.

Interface fields are public, static, and final by default, and the methods are public and abstract.

If we do not specify an access modifier or keyword abstract when declaring a method, the java compiler will do it under the hood.

Also, when declaring fields, the compiler will add publicstatic, and final keywords.

An example where multiple classes inherit the same interface and the use of polymorphism in that case:

 

interface Vehicle {
  void move();
}

class Car implements Vehicle {
  @Override
  public void move() {
    System.out.println("The car is moving...");
  }
}

class Truck implements Vehicle {
 
  @Override
  public void move() {
    System.out.println("The truck is moving...");
  }
}

class Test {

  public static void main(String[] args) {
    Vehicle car = new Car();
    Vehicle truck = new Truck();

    car.move();
    truck.move();
  }
}
Output: The car is moving… The truck is moving…
 
An example of a class that implements two different interfaces. A class must inherit their abstract methods:
 
interface Vehicle {
  
  void move();
}

interface Runnable {
  
  void run();
}

class Car implements Vehicle, Runnable {
  @Override
  public void move() {
    System.out.println("Move...");
  }
    
  @Override
  public void run() {
    System.out.println("Run...");
  }
}

class Test {

  public static void main(String[] args) {
    Car car = new Car();
    car.move();
    car.run();
  }
}
Output: Move… Run…
 
Example of an interface containing default and static methods, which got introduced in Java 8:
 
interface Vehicle {
  String brand = "Ford";
   
  default void move() {
    System.out.println("The vehicle is moving...");
  }
    
  static String returnBrand() {
    return brand;
  }
}

class Car implements Vehicle {
}

class Test {

  public static void main(String[] args) {
    Vehicle car = new Car();
    car.move();
    System.out.println(Vehicle.returnBrand());
  }
}
Output: The vehicle is moving… Ford
 
As you can see, the Car class did not have to inherit the default method move(), because it is the default method with a body, and its implementation.
 
Also, a static method cannot be called using a variable that points to a Car object because it is bound to the interface itself. Instead, it must be called using the interface name.
 
The interface can inherit another interface. Only in that case the keyword extends will be used:
 
interface Runnable {
  
  void run();
}

interface Vehicle extends Runnable {
}

class Car implements Vehicle {
    
  @Override
  public void run() {
    System.out.println("Run...");
  }
}

class Test {
    
  public static void main(String[] args) {
    Vehicle car = new Car();
    car.run();
  }
}
Output: Run…
 
In the example above, the Vehicle interface did not have to inherit the run() method from the Runnable interface, but the Car class did have to inherit it.
 
That’s it!

Leave a Reply

Your email address will not be published.