Difference Between an Interface and an Abstract Class in Java

Mohammad Irfan Oct 12, 2023
  1. Similarities Between Abstract Class and Interface
  2. Differences Between Abstract Class and Interface
  3. When to Use Abstract Class and Interface?
  4. Abstract Class in Java
  5. Interface in Java
  6. Abstract Class Implementing an Interface
  7. Summary
Difference Between an Interface and an Abstract Class in Java

This tutorial introduces the difference between an Interface and an Abstract class in Java and also lists some example codes to understand the topic.

Abstraction is the process of hiding the implementation and only providing essential details to the user. Abstraction in Java is achieved via Abstract classes and Interfaces. Abstract classes and Interfaces have a few things in common, but there are major differences between them. Let’s first go through some of the things that are similar between the two.

Similarities Between Abstract Class and Interface

  • As discussed above, both abstract class and interface are used for abstraction.
  • Abstract classes and interfaces cannot be instantiated, i.e., we cannot create an object for them.
  • Subclasses must override the abstract methods defined in the abstract class or interface.

The above points pretty much summarize the similarities between the two. Let’s now look at some of the key differences between them.

Differences Between Abstract Class and Interface

Abstract Class Interface
The abstract keyword in Java is used to create or declare an abstract class. In Java, the interface keyword is used to create or declare a new interface.
A class can inherit the properties and methods of an abstract class by using the extends keyword. To implement an Interface in Java, we can use the implements keyword.
An abstract class can have abstract or non-abstract methods defined in it. Abstract methods are the ones that do not have any implementation provided for them. An interface can only have abstract methods in it. We can only provide method definition but not its implementation. After Java 8, we can also have default and static methods in Interfaces.
An abstract class can contain final or non-final variables(class attributes) in it. It can also contain static or non-static attributes. An interface can only contain static and final members, and no other type of member is allowed.
An abstract class can implement an interface and implement the methods of the interface. An interface cannot extend any other class and cannot override or implement abstract class methods.
An abstract class can extend other classes and can also implement interfaces. As discussed in the previous point, interfaces cannot extend other classes. But there is no restriction in implementing an interface.
Java does not support multiple inheritances via classes. Abstract classes, just like any other class, do not support multiple inheritances. The support for multiple inheritances in Java is provided through Interfaces. This is because Interfaces provide full abstraction.
Abstract Class members or attributes can be private, protected, or public. Attributes or members of an Interface are always public.

When to Use Abstract Class and Interface?

Abstract classes can provide partial or full abstraction. Interfaces, on the other hand, always provide full abstraction. An abstract parent class may be created for a few classes that have some common functionalities. Abstract classes are also preferred if you want more freedom of action.

Interfaces are preferred when we want to define a basic structure. The programmer can then build anything with this structure. Interfaces also support multiple inheritances. So a single class can implement multiple interfaces.

Overall it is a matter of choice and the task that needs to be accomplished. Both Abstract class and Interface are suitable for different purposes and should be used accordingly.

Abstract Class in Java

Let’s create an Abstract class and create child classes that extend it to understand the abstract class and its functionalities.

abstract class Bell {
  protected String sound;

  Bell() {
    this.sound = "ting";
  }
  // Abstract Method
  abstract public void ring();

  // Non-Abstract Methods
  public void increaseVolume() {
    System.out.println("Increasing Volume");
  }

  public void decreaseVolume() {
    System.out.println("Decreasing Volume");
  }
}
class SchoolBell extends Bell {
  @Override
  public void ring() {
    System.out.println("Ringing the School bell: " + sound);
  }
}
class ChruchBell extends Bell {
  @Override
  public void ring() {
    System.out.println("Ringing the Chruch Bell: " + sound);
  }
}
public class AbstractClassDemo {
  public static void main(String[] args) {
    SchoolBell sb = new SchoolBell();
    ChruchBell cb = new ChruchBell();

    // Using the overridden methods
    sb.ring();
    cb.ring();

    // Using the non-abstract methods of Bell class
    sb.increaseVolume();
    cb.decreaseVolume();
  }
}

Output:

Ringing the School bell: ting
Ringing the Chruch Bell: ting
Increasing Volume
Decreasing Volume

Interface in Java

Let’s replicate the same scenario using interfaces. We can no longer define non-abstract methods in the interface. Interface is the correct choice if the classes do not want a common implementation of the increaseVolume() and the decreaseVolume() methods.

interface Bell {
  String sound = "ting";
  // only abstract methods allowed in interface
  public void ring();
  public void increaseVolume();
  public void decreaseVolume();
}
class SchoolBell implements Bell {
  public void ring() {
    System.out.println("Ringing the School bell: " + sound);
  }
  @Override
  public void increaseVolume() {
    System.out.println("Increasing Volume of School Bell");
  }
  @Override
  public void decreaseVolume() {
    System.out.println("Decreasing Volume of School Bell");
  }
}
class ChruchBell implements Bell {
  public void ring() {
    System.out.println("Ringing the Chruch Bell: " + sound);
  }
  @Override
  public void increaseVolume() {
    System.out.println("Increasing Volume of Chruch Bell");
  }
  @Override
  public void decreaseVolume() {
    System.out.println("Decreasing Volume of Chruch Bell");
  }
}
public class InterfaceDemo {
  public static void main(String[] args) {
    SchoolBell sb = new SchoolBell();
    ChruchBell cb = new ChruchBell();

    // Using the overridden methods
    sb.ring();
    cb.ring();

    // Using the non-abstract methods of Bell class
    sb.increaseVolume();
    cb.decreaseVolume();
  }
}

Output:

Ringing the School bell: ting
Ringing the Chruch Bell: ting
Increasing Volume of School Bell
Decreasing Volume of Chruch Bell

Abstract Class Implementing an Interface

As discussed in the previous section, we can implement the methods of an interface in an abstract class. The following code demonstrates this.

interface Bell {
  String sound = "ting";
  // only abstract methods allowed in interface
  public void ring();
  public void increaseVolume();
  public void decreaseVolume();
}
abstract class AbstractBell implements Bell {
  public void increaseVolume() {
    System.out.println("Increasing Volume");
  }
  public void decreaseVolume() {
    System.out.println("Decreasing Volume");
  }
}

Summary

Abstraction is one of the most fundamental concepts used in object-oriented programming. Abstraction is used to hide the implementation and only provide the minimum essential details to the user. In Java, abstraction is accomplished by using Abstract classes or Interfaces. A major difference between the two is that Abstract classes can also provide partial abstraction, whereas Interface will always provide complete abstraction. In this tutorial, we discussed some of the key differences between the two.

Related Article - Java Interface