Difference between Interface and Abstract Class in Java

Abstract classes and interfaces are the two main building blocks of most Java APIs. This article will discuss the most glaring differences between interfaces and abstract classes.

1. Abstract Class

In simplest words, an abstract class is which is declared abstract using the keyword abstract. It may or may not contain any abstract method.

In the following example, TestAbstractClass has two methods, the first method is abstract, and the second method is a normal method.

public abstract class TestAbstractClass {

    public abstract void abstractMethod();
    public void normalMethod()  { ... method body ... }
}

Note that if we have an abstract method in the class, we must declare the class as abstract itself. An abstract method adds incompleteness to the class. Thus compiler wants to declare the whole class abstract.

JVM identifies an abstract class as an incomplete class that has not defined its complete behavior. Declaring a class abstract enforces only one thing: we can not create an instance of this class.

So why even bother creating a class that can not be instantiated at all? The answer is in its usage in solving some critical design issues.

The only way to use an abstract class in an application is to extend this class. Its subclasses, if not declared abstract again, can be instantiated.

class ChildClass extends TestAbstractClass {

  @Override
  public void abstractMethod() {
    //method body
  }
}

2. Interface

Interfaces are yet another basic building block of most Java APIs. An Interface defines contracts, which implementing classes need to honor. These contracts are essentially unimplemented methods. Java already has a keyword for unimplemented methods i.e. abstract. In Java, a class can implement any public interface, so all the methods declared in an interface need to be public only.

public interface TestInterface {

    void implementMe();
}

In the above example, any implementing class needs to override implementMe() method.

public class TestMain implements TestInterface {

    @Override
    public void implementMe() {
        //...
    }
}

3. Abstract Class implementing an Interface

There is only one scenario when we implement an interface and do not override its method i.e. declare the class itself abstract. As the AbstractClass is abstract and cannot be initiated, so the completeness of the class is not broken.

public abstract class AbstractClass implements TestInterface {
    //No need to override implementMe()
}

When a class extends the above AbstactClass, it must override the implementMe() method to make itself a complete class.

public class ChildClass extends AbstractClass {

    @Override
    public void implementMe() {
        //...
    }
}

4. Difference between Abstract Class vs. Interface

Let’s note down the differences between abstract classes and interfaces for a quick review:

  • Interfaces have all methods inherently public and abstract. We can not override this behavior by reducing the accessibility of methods. We can not even declare the static methods. Only public and abstract methods are allowed. On the other side, abstract classes are flexible in declaring the methods. We can define abstract methods with protected accessibility also. Additionally, we can also define static methods, provided they are not abstract. Non-abstract static methods are allowed.
  • Interfaces can’t have fully defined methods except for default methods. By definition, interfaces are meant to provide the only contract. Abstract classes can have non-abstract methods without any limitations.
  • A child class can extend only one parent class but can implement any number of interfaces. This property is often referred to as the simulation of multiple inheritance in java.
  • Interfaces are absolutely abstract and cannot be instantiated; A Java abstract class also cannot be instantiated but can be invoked if a main() method exists.

5. When to Use?

Always remember that choice between the interface or abstract class is not either/or scenario, where choosing anyone without proper analysis would yield the same results. A choice must be made very intelligently after understanding the problem at hand. Let us try to put some intelligence here.

5.1. Add Partial Behavior with Abstract Classes

Abstract classes let you define some behaviors; it makes them excellent candidates inside of application frameworks.

Let us take an example of HttpServlet. It is the main class you must inherit if you are developing a web application using Servlets technology. As we know, each servlet has definite life cycle phases, i.e. initialization, service, and destruction. What if each servlet we create, we have to write the same piece of code regarding initialization and destruction again and again? Surely, it will be a big pain.

JDK designers solved this by making HttpServlet abstract class. It has all the basic code already written for the initialization of a servlet and its destruction of it also. You only need to override certain methods where you write your application processing-related code, that’s all. Make sense, right !!

Can you add the above feature using the interface? No, even if you can, the design will be like a hell for most innocent programmers.

5.2. Use Interfaces for Contracts Only Behavior

Now, let’s look at the usage of interfaces. An interface only provides contracts, and it is the responsibility of implementing classes to implement every single contract.

An interface is the best fit for cases where you want to define only the characteristics of class, and you want to force all implementing entities to implement those characteristics.

I would like to take an example of Map interface in the collections framework. It provides only rules, how a map should behave in practice. e.g. it should store the key-value pair, the value should be accessible using keys etc. These rules are in form of abstract methods in the interface.

All implementing classes ( such as HashMap, HashTable, TreeMap or WeakHashMap) implements all methods differently and thus exhibit different features from the rest.

Also, interfaces can be used in defining the separation of responsibilities. For example, HashMap implements 3 interfaces: Map, Serializable and Cloneable. Each interface defines separate responsibilities; thus, an implementing class chooses what it wants to implement and will provide that much-limited functionality.

6. Java 8 Default Methods in Interfaces

With Java 8, you can now define methods in interfaces. These are called default methods. Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

As the name implies, default methods in Java 8 are simply default. If you do not override them, they are the methods that caller classes will invoke.

public interface Moveable {

    default void move(){
        System.out.println("I am moving");
    }
}

In the above example, Moveable interface defines a method move() and provided a default implementation as well. If any class implements this interface then it need not to implement its own version of move() method. It can directly call instance.move().

public class Animal implements Moveable {

    public static void main(String[] args){

        Animal tiger = new Animal();
        tiger.move();   //I am moving
    }
}

And if the class willingly wants to customize the behavior then it can provide its own custom implementation and override the method. Now its own custom method will be called.

public class Animal implements Moveable {
      
    public void move(){
        System.out.println("I am running");
    }
      
    public static void main(String[] args){
        Animal tiger = new Animal();
        tiger.move();   //I am running
    }
}

7. Difference between Abstract Class and Interface in Java 8

Since Java 8, we can now provide a partial implementation with interfaces using the default methods, just like abstract classes. So essentially, the line between interfaces and abstract classes has become very thin. They provide almost the same capabilities now.

Now, one big difference remains that we cannot extend multiple classes, whereas we can implement multiple interfaces. Apart from this difference, you can achieve any possible functionality from interfaces that abstract classes can make possible, and vice-versa is also true.

I hope you found enough information on interfaces and abstract classes in java.

Happy learning !!

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode