Java supports OOP that consists of four main pillars and abstraction is one of them. Abstraction hides the implementation part and provides only specific stuff to the user. Like showing the website frontend instead of the backend. To achieve abstraction, Java offers two approaches namely “abstract” class and “interface”. 

Their main difference is the implementation process and how much they provide an abstraction for classes. The “abstract” class can provide abstraction from “0%” to “100%” and “interface” always provides “100%” abstraction. However, they also have similarities like both don’t have implementation codes, and abstract methods are initialized in their child classes.

This guide explains the core difference between abstract class and interface in Java by covering the following:

  • What is an Interface in Java?
  • What is an Abstract Class in Java?
  • Difference Between Abstract Class and Interface in Java
  • Conclusion

What is an Interface in Java?

The “interface” is more like a sketch to implement the classes. Because it contains only the declaration part of many abstract methods. The initialization part of these methods is placed inside the specific child classes. The “interface” offers maximum abstraction by placing the declaration and initialization part of abstract methods at different places. It achieves polymorphism(Same method with different definitions) by allowing methods to perform operations according to specified scenarios.

Syntax of Interface

interface myInterface{
//your abstract methods Declaration
}

Pro Tip

Interfaces do not provide partial abstraction, it always offers a high level of abstraction. The child classes inherit properties from the interfaces using the “implements” keyword. 

Why Use Interface?

The “interface” should be used in the below-mentioned scenarios:

  • To gain a higher level of abstraction in your code.
  • To set the default type of class variables and member functions to “public static final”. This type is set automatically by the interface and the user can’t modify it.
  • To perform “multiple” inheritance by inheriting more than one interface at a time.
  • To achieve loose coupling and gain dynamic method resolution type of perks.

Let’s take a look at the below code for the practical implementation of an “interface”:

interface interfaceSudents{
//no implementation is required
void noise();
void move();
}
class girls implements interfaceSudents{
@Override
public void noise() {
  System.out.println("Stop Shouting => Abstract Method Implementation!");
}
@Override
public void move() {
  System.out.println("Stay at One Place => Abstract Method Implementation!");
}
}
class boys implements interfaceSudents{
@Override
public void noise() {
  System.out.println("Keep your Voice Down => Abstract Method Implementation!");
}
@Override
public void move() {
  System.out.println("Hold the Ground => Abstract Method Implementation!");
}
}
public class starter{
public static void main(String[] args) {
  System.out.println("Using Interfaces to Achieve Full Abstraction");
  girls girlsStud = new girls();
  boys boysStud = new boys();
  girlsStud.noise();
  girlsStud.move();
  System.out.println();

  boysStud.noise();
  boysStud.move();
}
}

The working of the above code is written below:

  • First, create an interface named “interfaceSudents”. This interface contains two declared abstract methods named “noise()” and “move()”.
  • Then, define a class named “girls” which inherits the properties of an “interfaceStudents” using the “implements” keyword. 
  • Next, override the abstract methods “noise()” and “move()” according to the requirements using the “@Override” annotation.
  • After that, create a class named “boys” that inherits properties from the “interfaceSudents” interface. It also overrides the mentioned abstract methods via the “@Override” annotation.
  • Finally, create a “starter” class and define a “main()” init. Inside this method, create objects for the “girls” and “boys” classes and use these objects to invoke the abstract “noise()” and “move()” methods. 

The generated output shows the working of an interface:

What is an Abstract Class in Java?

An “abstract” class is created using the “abstract” keyword and must contain at least one abstract method. It provides low abstraction if the abstract methods are implemented inside the “abstract” class. For higher abstraction, the abstract methods are just declared in the abstract class and implemented in inherited classes. It provides freedom by allowing users to define the type of data variables and the member function according to requirements. They are not bound to be “static” and “final” types like interfaces.

Syntax of Abstract Class

abstract class myAbstractClass{
// Abstract Methods with or without implementation
}

When To Use Abstract Class?

The scenarios in which the usage of abstract class is the best option are stated below:

  • When you want to achieve partial or full abstraction.
  • To enhance code reusability by providing abstract methods as templates for future implementation.
  • There is no restriction on applying the access modifier or type of the data members and member functions.

Let’s consider a couple of examples to understand the workings of abstract classes.

Pro Tip:

The abstract methods with no implementation inside the abstract class achieve higher abstraction. The methods having the implementation part inside the abstract class gain a low level of abstraction. These methods are known as “concrete” methods.

Achieving Full Abstraction With Abstract Class

In the “full” abstraction, all implementation works are hidden from the user and only specific stuff gets displayed. The full abstraction using abstract class is done by only declaring the abstract methods i.e. methods without any implementation. Then initialize these abstract methods inside the desired classes using the “@Override” annotation(Recommended but not compulsory):

abstract class abstractClass {
  //no implementation
  public abstract void noise();
  public abstract void move();
}
class girls extends abstractClass {
  @Override
  public void noise() {
  System.out.println("Stop Shouting => Abstract Method Implementation!");
  }
  @Override
  public void move() {
  System.out.println("Stay at One Place => Abstract Method Implementation!");
  }
}
class boys extends abstractClass {
  @Override
  public void noise() {
  System.out.println("Keep your Voice Down => Abstract Method Implementation!");
  }
  @Override
  public void move() {
  System.out.println("Hold the Ground => Abstract Method Implementation!");
  }
}
public class starter{
public static void main(String[] args) {
  girls girlsStud = new girls();
  boys boysStud = new boys();
  girlsStud.noise();
  girlsStud.move();
  System.out.println();
  boysStud.noise();
  boysStud.move();
}
}

In the above code:

  • First, create an abstract class named “abstractClass”. Inside it, declare two “abstract” methods namely “noise()” and “move()”.
  • Next, create a class “girls” which inherits the properties of “abstractClass” using the “extends” keyword.
  • This class implements or defines the “noise()” and “move” methods using the “@Override” annotation.
  • The same procedure is repeated for the inherited “boys” class and it overrides the abstract methods as well. 
  • After that, define a “main()” method inside the “starter” class. Inside the “main()” method, create objects for both “girls” and “boys” classes namely “girlsStud” and “boysStud”. 
  • Finally, invoke the abstract “noise()” and “move()” methods separately using both created objects.

The generated output confirms the working of an abstract class to achieve full abstraction:

Achieving Partial Abstraction With Abstract Class

Partial abstraction is achieved when there is a combination of abstract and concrete methods inside the abstract class:

abstract class abstractCarClass {
public void engineInitiator() {
  System.out.println("Car Engine is started => Abstract Method with Implementation.");
}
public abstract void hitGas();
}
class SportsCar extends abstractCarClass {
@Override
public void hitGas() {
  System.out.println("Executed Part from SportsCar class");
}
}

class FamilyCar extends abstractCarClass {
@Override
public void hitGas() {
  System.out.println("Executed Part from FamilyCar class!");
}
}
public class starter {
public static void main(String[] args) {
  SportsCar mySportsCar = new SportsCar();
  FamilyCar myFamilyCar = new FamilyCar();
  mySportsCar.engineInitiator();
  mySportsCar.hitGas();
  System.out.println();

  myFamilyCar.engineInitiator();
  myFamilyCar.hitGas();
}
}

The explanation of the above code is as follows:

  • First, create an abstract class named “abstractCarClass” using the “abstract class” keyword.
  • Now, create two abstract methods with and without implementation “engineInitiator()” and “hitGas()” respectively
  • Next, define a new class “SportsCar” which inherits the properties of “abstractCarClass” using the “extends” keyword.
  • This class implements the abstract “hitGas()” method by the utilization of the “@Override” annotation.
  • Then, another class “FamilayCar” which is a child of the “abstractCarClass” is created. Inside it, define the “hitGas()” abstract method using the “@Override” annotation.
  • Now, define a “main()” method inside the “starter” class.
  • Then, create instances “mySportsCar” and “myFamilyCar” for the “SportsCar” and “FamilyCar” classes respectively.
  • Finally, invoke both methods of the “abstractCarClass” using created instances to ensure the working of an abstract class.

The output shows that partial abstraction is achieved using the abstract class:

Difference Between Abstract Class and Interface in Java

The core differences between abstract class and interface are stated below in the tabular form:

ParameterAbstract ClassInterface
CreationThe abstract class is created using the “abstract class” keyword.The interface class is created using the “interface” keyword.
Abstract MethodIt contains the abstract method and concrete methods according to requirements.Only consists of abstract methods and they are declared inside the interface scope.
Abstract Method DeclarationThe methods are declared with the “abstract” keyword and access modifier.The methods are declared without any keyword or access modifier.
Class MembersThe class members can be of any type.The class members must be of the “public static final” type.
InheritanceIt inherits using the “extends” keyword and only one abstract class can be inherited, multiple is not allowed.It inherits using the “implements” keyword and can implement multiple interfaces.
ExtendabilityIt can extend or implement classes and interfaces.It can only extend Java interfaces.
ConstructorsAn abstract class can contain constructors.The constructors are not available.
Where to UsePrevention of DependenciesFuture enhancement and to encourage loose coupling.

This guide has highlighted the key differences between abstract classes and interfaces in Java.

Conclusion

The “abstract class” and “interface” are mainly used to gain abstraction for classes. The “abstract class” contains both abstract and concrete methods to provide partial abstractions, for full abstraction only abstract methods are placed. On the other hand, the “interface” always provides full abstraction and it must contain one abstract method, the insertion of concrete methods is not allowed in the interface. This guide has illustrated the differences between abstract classes and interfaces in Java.