Interface vs. Abstract Class in Java: Explained with Examples

  • Last updated Apr 25, 2024

The main difference between an interface and an abstract class in Java is their purpose and how they are used.

An interface in Java is a set of rules that a class agrees to follow. It acts as a blueprint that specifies what methods a class should have. An interface only has method declarations (without any code), constants, and default methods. It doesn't have variables. A class can implement multiple interfaces and must provide the implementation for the methods defined in the interface.

On the other hand, an abstract class in Java is a special class that is not complete on its own, so it cannot be used directly. Instead, it is meant to be inherited by other classes. An abstract class can have methods that are just declared (like in an interface) and methods that already have some code. It can also have variables, constructors, and other regular class features. However, a class can only inherit from one abstract class.

The following table shows a clear explanation of the distinctions between these two important concepts in Java programming:

Interface Abstract Class
The interface keyword is used to declare an interface.
The abstract keyword is used to declare an abstract class.
Interface can only have abstract methods. Since Java 8, interface can also contain default and static methods.
Abstract class can contain both abstract and non-abstract methods.
It supports multiple inheritance.
It doesn’t support multiple inheritance.
An Interface cannot have a constructor.
An Abstract class can have any number of constructors.
By default any methods declared in the interface are public abstract.
It can contain any type of method. There is no restriction on abstract class method modifiers. A method doesn’t have to be a public abstract. It can be private, protected, etc.
By default variables are public static final in the interface. Interface can only contain static final variables.
Abstract class can contain static, non-static, final and non-final variables.
A class can implement an interface by using the implements keyword.
A class can be extended from an abstract class by using the extends keyword.


Interface Example

Here's an example of an interface in Java:

public interface Drawable {
     
    // Declare a constant
    int MAX_WIDTH = 800;
    int MAX_HEIGHT = 500;

    // Declaring a method without any implementation
    void draw();

    // Declare a default method with implementation
    default void display() {
        System.out.println("Displaying the drawable object.");
    }

}

In this example, we have created an interface named Drawable. It declares constants MAX_WIDTH with a value of 800 and MAX_HEIGHT with a value of 500. It also declares a single method called draw() without providing any implementation. Additionally, the interface includes a default method display() with an implementation that prints a message to the console.

Other classes can implement this interface and provide their own implementation for the draw() method. They will also have access to the constant MAX_WIDTH and can optionally override the default method display().

Here's an example class that implements the Drawable interface:

public class Circle implements Drawable {

    @Override
    public void draw() {
        System.out.println("Drawing a circle.");
    }

}

In this case, the Circle class implements the Drawable interface and provides its own implementation for the draw() method. It can also use the constants MAX_WIDTH and MAX_HEIGHT defined in the interface and optionally override the default method display() if needed.

Here's a simple example of how the above Drawable interface can be used in code:

public class Example {

   public static void main(String [] args) {
		
      //Creating an instance of Drawable interface from Circle class
      Drawable drawable = new Circle();
		
      //Calling methods
      drawable.draw();
      drawable.display();
   }
}

Here, we have a class named "Example" that contains the main method, which is where the program starts running. Inside the main method, we create an object named "drawable" of the "Drawable" interface. We assign this object a new Circle object using the statement Drawable drawable = new Circle();. This means that we are treating the Circle object as a Drawable object. Next, we call the draw() method on the "drawable" object using the statement drawable.draw();. This executes the code inside the draw() method of the Circle class because the object is actually a Circle. We also call the display() method on the "drawable" object using the statement drawable.display();. This method is provided by the Drawable interface with a default implementation. So, it will be executed unless the Circle class overrides it with its own implementation.

Interfaces in Java help define common rules or contracts for classes to follow. They allow different classes to share similar behaviors, making it easier to reuse code and create more abstract and flexible programs.


Abstract Class Example

Here's an example of an abstract class in Java:

// Defining an abstract class named "Animal"
public abstract class Animal {

    // Instance variables
    private String name;
    private String color;

    // Constructor
    public Animal(String name, String color) {
        this.name = name;
        this.color = color;
    }

    // Abstract methods
    public abstract void sound();
    public abstract void color();

    // Concrete method
    public void eat() {
        System.out.println(name + " is eating.");
    }
    
}

In this example, we created an abstract class named "Animal". It has two instance variables, "name" and "color", which store the name and color of the animal respectively. These variables are marked as private, meaning they can only be accessed within the class. The class has a constructor that takes two parameters, "name" and "color". When an object of the Animal class is created, the constructor sets the values of the name and color variables based on the provided arguments. The abstract class declares two abstract methods called "sound()" and "color". These methods are declared without any implementation using the abstract keyword. Any class that inherits from the Animal class must provide its own implementation of the sound() and color() methods. Additionally, the abstract class has a concrete method called "eat()". This method has an implementation, which simply outputs a message stating that the animal with the given name is eating. Concrete methods are fully implemented and can be used as-is or overridden by subclasses. It provides a default implementation, meaning it has code inside it and does not need to be implemented by subclasses. Subclasses can use this method as-is or override it if necessary.

Here's an example of a subclass that extends the abstract class:

public class Dog extends Animal {
    public Dog(String name, String color) {
        super(name, color);
    }

    @Override
    public void sound() {
        System.out.println(name + " is barking.");
    }

    @Override
    public void color() {
        System.out.println("Color of " + name + " is " + color);
    }
}

Here, we have created a class named "Dog" that extends the abstract class "Animal". This means that the Dog class inherits the characteristics and behaviors defined in the Animal class.

The Dog class has a constructor that takes two parameters, "name" and "color". This constructor calls the superclass constructor using the super(name, color) statement. This ensures that the name and color values are passed to the Animal class's constructor for initialization. The Dog class overrides the abstract method "sound()" defined in the Animal class. The @Override annotation indicates that we are providing a specific implementation for this method in the Dog class. In this case, the sound() method is implemented to output a message indicating that the dog is barking. The name variable is used to retrieve the name of the dog. Additionally, the Dog class overrides the color() method from the Animal class. This method is not defined in the Animal class in the given code snippet, but assuming it is a valid method in the Animal class, we override it here. The overridden color() method outputs a message indicating the color of the dog, using both the name and color variables.


Use Interface

Use an interface when:

  • You want to define a contract or a set of rules that classes must follow.
  • You want to provide a common behavior that can be implemented by multiple unrelated classes.
  • You want to achieve a high level of abstraction and create loosely coupled code.
  • You don't need to provide any default method implementations or state (variables) within the contract.


Use Abstract Class
  • You want to provide a base implementation or common functionality to a group of related classes.
  • You want to share code among multiple subclasses.
  • You want to define methods with default implementations that subclasses can override.
  • You want to define variables (state) that can be used by subclasses.
  • You want to restrict direct instantiation of the class.

In summary, use an interface when you want to define a contract or provide common behavior to unrelated classes. Use an abstract class when you want to provide a base implementation, share code among related classes, or define variables and default method implementations for subclasses.