Blog Java

Difference Between Abstract Class and Interface Java

In object-oriented programming, both interfaces and abstract classes are used to create contracts for classes to follow. But they serve different purposes and are used in different contexts. Let’s dive into the details.

What is an Interface?

An interface is a contract 🤝 that guarantees that a class implements a certain set of methods. It’s useful when you want to ensure that different classes adhere to a certain API, even if they share no implementation details. In Java, a class can implement multiple interfaces.

For example, in Java 8, the java.util.Comparator interface guarantees that any class implementing it will have a compare() method.

Java
Comparator<Integer> comparator = (Integer o1, Integer o2) -> o1.compareTo(o2);

What is an Abstract Class?

An abstract class, on the other hand, is a class that cannot be instantiated on its own and must be extended. It can contain both abstract methods (which have no implementation and must be overridden) and concrete methods (which have an implementation and can optionally be overridden).

For example, java.io.InputStream is an abstract class in Java 8 library that provides methods for reading bytes, arrays of bytes, or lines of text, but leaves the implementation of some methods to its subclasses.

Java
public abstract class InputStream implements Closeable {
    public abstract int read() throws IOException;
    // Other methods...
}

What is Difference between Abstract class and Interface?

The choice between an interface and an abstract class will depend on your specific needs and the design of your application.

  • Use an interface when: You need to define a capability that can be implemented by many unrelated classes. For example, the Runnable interface in Java is used to ensure that a class can be executed by a thread.
  • Use an abstract class when: You have a base class that provides common functionality but also needs to declare abstract methods to be implemented by subclasses. For example, the java.util.AbstractCollection class in Java provides some common functionality for collections but leaves the specific implementation of some methods to its subclasses.

Real-Time Differences

In real-time scenarios, the choice between an interface and an abstract class depends on the specific requirements of your design.

  • Interface: If you’re designing a system where multiple classes need to implement a common behavior, but don’t necessarily share any implementation details, an interface would be a good choice.
  • Abstract Class: If you’re designing a system where several classes share some common behavior, but also have their own unique behaviors, an abstract class would be a good choice.

Instance Variables in Interfaces and Abstract Classes

One of the key differences between interfaces and abstract classes in Java lies in the way they handle instance variables.

Interfaces: In an interface, you can declare but not instantiate variables. By default, any variable declared in an interface is public, static, and final. This means that it’s essentially a constant, and the same value is shared across all instances of classes that implement the interface.

Java
interface MyInterface {
    int CONSTANT = 10;  // This is a constant, not an instance variable
}

Abstract Classes: On the other hand, an abstract class can have instance variables. These are variables that belong to each individual object that’s created from the class. Each instance of the class can have different values for these variables.

Java
abstract class MyAbstractClass {
    int instanceVariable;  // This is an instance variable
}

Difference based on Lambda Expressions and Functional Interfaces

In Java 8, a new feature was introduced called lambda expressions. Lambda expressions are anonymous functions that you can use to create delegates or expression tree types. They are used primarily to define inline implementation of a functional interface, i.e., an interface with a single method only.

Java
// A functional interface
interface MyInterface {
    void display();
}

public class Main {
    public static void main(String[] args) {
        // Implementing the interface using a lambda expression
        MyInterface myInterface = () -> System.out.println("Hello, World!");
        myInterface.display();
    }
}

In the above example, MyInterface is a functional interface with a single method display(). We create an instance of this interface using a lambda expression () -> System.out.println("Hello, World!");.

On the other hand, abstract classes can have any number of methods, and they can’t be instantiated directly. An abstract class can provide a default behavior (implemented methods) that we can extend (inherit) in our classes. But we can’t use lambda expressions to create instances of an abstract class.

Difference based on Design patterns to show the difference between Abstract class and Interface

The Strategy pattern is a behavioral design pattern that turns a set of behaviors into objects and makes them interchangeable inside the original context object. The original object, called context, holds a reference to a strategy object and delegates it executing the behavior. In order to switch a strategy at runtime, the context replaces the strategy object with another one. In Java, the Strategy pattern can be implemented using an interface.

Java
interface SortingStrategy {
    void sort(int[] numbers);
}

class BubbleSortStrategy implements SortingStrategy {
    public void sort(int[] numbers) {
        // Implement bubble sort
    }
}

class QuickSortStrategy implements SortingStrategy {
    public void sort(int[] numbers) {
        // Implement quick sort
    }
}

The Template Method pattern is a behavioral design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure. The Template Method pattern suggests that you break down an algorithm into a series of steps, turn these steps into methods, and put a series of calls to these methods inside a single template method. The steps may either be abstract, or have some default implementation. To use the algorithm, the client is supposed to provide its own subclass, implement all abstract steps, and override some of the optional ones if needed. In Java, the Template Method pattern can be implemented using an abstract class.

Java
abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    // Template method
    public final void play() {
        initialize();
        startPlay();
        endPlay();
    }
}

class Cricket extends Game {
    void initialize() { /* Cricket specific initialization */ }
    void startPlay() { /* Cricket specific start play */ }
    void endPlay() { /* Cricket specific end play */ }
}

class Football extends Game {
    void initialize() { /* Football specific initialization */ }
    void startPlay() { /* Football specific start play */ }
    void endPlay() { /* Football specific end play */ }
}

I hope this addition helps clarify the differences between interfaces and abstract classes in Java, especially in the context of lambda expressions and functional interfaces! 😊

Ref:

  1. https://shixseyidrin.medium.com/abstract-class-vs-interface-c07c6ddc8f18
  2. https://medium.com/@alifabdullah/easiest-explanation-of-abstract-class-and-interface-280741bc2daf
Avatar

Neelabh

About Author

As Neelabh Singh, I am a Senior Software Engineer with 6.6 years of experience, specializing in Java technologies, Microservices, AWS, Algorithms, and Data Structures. I am also a technology blogger and an active participant in several online coding communities.

You may also like

Blog Design Pattern

Understanding the Builder Design Pattern in Java | Creational Design Patterns | CodeTechSummit

Overview The Builder design pattern is a creational pattern used to construct a complex object step by step. It separates
Blog Tech Toolkit

Base64 Decode

Base64 encoding is a technique used to encode binary data into ASCII characters, making it easier to transmit data over