Interface in Java

In this article, we are going to discuss the Interface in Java topic. We will define interface in Java, and study the use of interface in Java, its syntax, features, etc. So, let us start by defining the interface in Java.

What is Interface in Java?

An interface in Java is usually referred to as the “Blueprint of a Class”. This means that by looking at an interface, we can predict the behavior of the classes that will implement this interface.

Interfaces are used to achieve abstraction in Java. Abstraction is one of the major pillars of Object-Oriented Programming Systems (OOPS).

If we go into the definition of an interface, we can say that an interface in Java is an abstract type used to show the behavior of a class as it acts like a blueprint for the classes that implement it.

The classes are inherited whereas, the interfaces are implemented. The interfaces in Java represent the HAS-A relationship.

An interface is just like a class. It can have methods and data members. However, by default, all the methods in an interface are abstract i.e. they don’t have a body. Also, all the data members are final and static, by default.

Since in an interface, the methods are abstract, we cannot instantiate an interface. This means that the object of an interface cannot be created.

Let us understand the meaning of an interface with the help of an example.

import java.util.*;
class Phone {
    void makeCall(String person) {  
    }
    void sendMessage(String person) {   
    }
}
interface Camera {
    void clickPicture();
    void recordVideo();
}
class SmartPhone extends Phone implements Camera{
    public void clickPicture() {
        System.out.println("Auto focus on human face");
    }
    public void recordVideo() {
        System.out.println("Auto removal of background noise");
    }
    public void accessInternet() {
        System.out.println("Woah! I'm smart enough to do this");
    }
}
public class Main {
    public static void main(String[] args) {     
    }
}

So, in the above program, we have 2 classes, Phone and Camera, and one interface SmartPhone. These classes represent real-world entities. Now, we need to identify the relationship between these 3 classes.

So, as we can see that the class SmartPhone in our program extends the class Phone and implements the Interface Camera. This is because inheritance represents an IS-A relationship i.e. SmartPhone is a Phone. However, the interfaces represent a HAS-A relationship i.e. the SmartPhone has a Camera.

Syntax of Interface in Java

We saw in the code above, in order to use an interface, we have to use the ‘implements’ keyword in Java. Also, all the methods are abstract by default and hence we cannot write a body for those methods declared in an interface.

interface InterfaceName {
// by default Final and static
Final static datatype variableName;
// by default abstract
returnType FunctionName(params);
}
class ClassName implements InterfaceName {
// override all the methods of the interface
//so that the class become concrete
}

Some rules regarding the usage of Interface in Java

  1. The use of interface in Java is to achieve total abstraction i.e. all the methods will be abstract, unlike Classes in which there can be some methods abstract while others can be non-abstract.
  2. Java does not support multiple inheritance in the case of Classes. This means that more than 1 class cannot be extended at a time.
  3. Abstract classes may contain variables that are non-final and methods that are not static. However, the Interfaces contain variables that are always final and static.
  4. As soon as you implement an interface to a class, it becomes abstract. How to make it concrete? We have discussed this point in detail below.

Let us further extend our previous program to implement multiple interfaces and add some data types to the interfaces as well so that we can understand the concept in more detail.

import java.util.*;
class Phone {    
    void makeCall(String person) {        
    }    
    void sendMessage(String person) {        
    }
}
interface Camera {    
    int megaPixels = 48;    
    void clickPicture();    
    void recordVideo();
}
interface Calculator {    
    void add(int x,int y);
    void subtract(int x, int y);
    void multiply(int x, int y);
    void divide(int x, int y);
}
class SmartPhone extends Phone implements Camera, Calculator{
    public void clickPicture() {
        System.out.println("Auto focus on human face");
    }    
    public void recordVideo() {
        System.out.println("Auto removal of background noise");
    }  
    public void accessInternet() {
        System.out.println("Woah! I'm smart enough to do this");
    }
    public void add(int x, int y) {
        System.out.println(x + y);
    }
    public void subtract(int x, int y) {
        System.out.println(x - y);
    }
    public void multiply(int x, int y) {
        System.out.println(x * y);
    }
    public void divide(int x, int y) {
        System.out.println(x / y);
    }
}
public class Main {
    public static void main(String[] args) {
        SmartPhone PrepPhone = new SmartPhone();
        PrepPhone.clickPicture();
        PrepPhone.add(10,20);
    }
}

So, as you can see in the code above, we have 2 classes, Phone, and SmartPhone. Also, we have 2 interfaces Camera and a Calculator. So, a SmartPhone is not a Camera and a Calculator, rather, it is a Phone that has a Camera and a Calculator.

So, inheritance is used to depict the IS-A relationship between a Phone and a SmartPhone whereas Interfaces are implemented to depict the HAS-A relationships between the SmartPhone, Calculator, and Camera.

We can see that the Camera has a data member called ‘megaPixels’. We have not declared it final and static. However, it is final and static by default as it is created inside an interface.

Also, we have overridden all the methods of both the Camera and the Calculator interfaces in the SmartPhone class. This is because if we implement an interface (that has all the abstract methods), we have to override all the methods of the interface in that class to prevent the class from being abstract (Discussed in Point No 4).

Also, you can try to change the value of ‘megaPixels’. It will not change as it is a final variable.

So, these were all the basics of Interface in Java. However, there were some changes made to the interface in Java JDK 8 version. So, let us learn what new changes were made to it.

New Features of Interface in Java JDK 8

  1. Now, you can have default methods within an interface i.e. the methods that are not public and abstract. So, there can be some methods in an interface that have a body and they need to be default. Now, you might ask about the need for this feature. Suppose that we want to add a new function to the interface. Now, all the classes implementing the interface will have to override that function. To avoid that, now we can make a function default and add its body so that we have provided some body to the function in the interface and the classes that need their own version of that function, can override it, the rest can leave it as it is not abstract and will not affect the Class. However, this rules out the total abstraction concept which was actually the aim of the interface in Java.
  2. Another new feature of adding a static method to an interface was introduced in Java JDK 8. This is because we can’t instantiate an interface and static methods are called without creating an object. So, we will be able to use certain methods without creating the object of that interface. These will not be abstract and will not be inherited.

So, let us look at 2 programs depicting the implementation of the above 2 new features of Interface in Java added in JDK 8.

import java.util.*;
interface i1 {
    void meth1();
    void meth2();    
    default void meth3() {
        System.out.println("This is the default method for this interface");
    }
}
class A implements i1{
    public void meth1() {
        System.out.println("Class A implementation of meth1");
    }    
    public void meth2() {
        System.out.println("Class A implementation of meth2");
    }    
    public void meth3() {
        System.out.println("Class A implementation of meth3");
    }
}
class B implements i1 {
    public void meth1() {
        System.out.println("Class B implementation of meth1");
    }    
    public void meth2() {
        System.out.println("Class B implementation of meth2");
    }
}
public class Main {    
    public static void main(String[] args) {
        A objA = new A();
        objA.meth1();
        objA.meth2();
        objA.meth3();        
        B objB = new B();
        objB.meth1();
        objB.meth2();
        objB.meth3();
    }
}

So, as you can see in the above program, we have an interface i1 that has 2 abstract methods and 1 default method. Also, there are 2 classes A and B, both implementing the interface i1. The difference between the 2 classes is that class A has overridden the default method of the interface i1 whereas Class B has not. We can assume this to be the case that classes A and B were prewritten and we wanted to add a method in the interface that is aligning with the properties of class A and not B. So, class A has its own version of that default method meth3(), and since class B does not need it, it does not override it.

However, the default methods of interfaces get inherited. This can be seen when we run the code and see that the meth3() can be called using an object of class B and gives the output according to the default methods of interface i1.

Now, let us understand the second new feature with the help of a program.

import java.util.*;
interface i1 {
    void meth1();
    void meth2();    
    default void meth3() {
        System.out.println("This is the default method for this interface");
    }    
    static void meth4() {
        System.out.println("Static method can be called without using object");
    }
}
class A implements i1{
    public void meth1() {
        System.out.println("Class A implementation of meth1");
    }    
    public void meth2() {
        System.out.println("Class A implementation of meth2");
    }    
    public void meth3() {
        System.out.println("Class A implementation of meth3");
    }
}
class B implements i1 {
    public void meth1() {
        System.out.println("Class B implementation of meth1");
    }    
    public void meth2() {
        System.out.println("Class B implementation of meth2");
    }
}
public class Main {    
    public static void main(String[] args) {
        A objA = new A();
        objA.meth1();
        objA.meth2();
        objA.meth3();        
        B objB = new B();
        objB.meth1();
        objB.meth2();
        objB.meth3();
        i1.meth4();
    }
}

So, we have used the same program as above to keep the flow of understanding simple. However, we have just added one static method into the interface i1. This method is not inherited by any class and this method can be called directly by using the interface i1.

Some new features added to JDK 9 were that interfaces can now have private methods and private static methods too.

So, this was all about the interfaces in Java. We have discussed the meaning, uses, needs, and features of Interface in Java along with the implementation. We hope that you liked the discussion. See you again at PrepBytes.

Leave a Reply

Your email address will not be published. Required fields are marked *