Skip to main content

Interfaces vs. Abstract Classes

In Java's object-oriented programming (OOP) paradigm, both interfaces and abstract classes provide mechanisms for achieving abstraction and polymorphism. While they share some similarities, their primary purposes, capabilities, and use cases differ significantly.

Interfaces

An interface in Java is a blueprint of a class. It can have static final fields (constants) and abstract methods. From Java 8 onwards, interfaces can also have default and static methods. From Java 9 onwards, private methods are also allowed.

Key Characteristics:

  • 100% Abstraction: Historically, all methods in an interface were implicitly public abstract and had no implementation.
  • Fields: Can only declare public static final fields (constants). These are implicitly public static final.
  • Methods:
    • public abstract methods (implicitly).
    • default methods (from Java 8) provide a default implementation that implementing classes can override.
    • static methods (from Java 8) are utility methods related to the interface itself, not its implementing objects.
    • private and private static methods (from Java 9) to support default and static methods within the interface.
  • Constructors: Cannot have constructors.
  • Inheritance: A class implements an interface. A class can implement multiple interfaces (multiple inheritance of type). An interface can extend multiple other interfaces.
  • Access Modifiers: All members are implicitly public (except private methods).

Use Cases:

  • Defining Contracts: Interfaces are ideal for defining contracts that classes must adhere to. Any class implementing an interface guarantees to provide implementations for its abstract methods.
  • Achieving Multiple Inheritance of Type: Since a class can implement multiple interfaces, it can acquire behaviors from multiple sources, bypassing Java's single inheritance limitation for classes.
  • Loose Coupling: Promotes loose coupling by allowing classes to interact based on defined interfaces rather than concrete implementations.
  • Callback Mechanisms: Often used for defining callback methods.

Example:

interface Shape {
double PI = 3.14159; // public static final by default

double calculateArea(); // public abstract by default
double calculatePerimeter();

default void display() { // Default method
System.out.println("This is a shape.");
}
}

class Circle implements Shape {
private double radius;

public Circle(double radius) {
this.radius = radius;
}

@Override
public double calculateArea() {
return PI * radius * radius;
}

@Override
public double calculatePerimeter() {
return 2 * PI * radius;
}
}

Abstract Classes

An abstract class is a class that cannot be instantiated on its own and may contain abstract methods (methods without an implementation) as well as concrete (implemented) methods. It serves as a base class for other classes, providing common functionality and defining a template for subclasses.

Key Characteristics:

  • Partial Abstraction: Can have both abstract methods and concrete methods. It can be 0% abstract (no abstract methods but still declared abstract) or up to 100% abstract (all methods are abstract).
  • Fields: Can have any type of fields (static, non-static, final, non-final) with any access modifier (public, protected, private, default).
  • Methods: Can have abstract methods (declared with the abstract keyword) and concrete methods.
  • Constructors: Can have constructors. These constructors are called when a concrete subclass is instantiated.
  • Inheritance: A class extends an abstract class. A class can extend only one abstract class (single inheritance). An abstract class can extend another class or abstract class and can implement interfaces.
  • Access Modifiers: Members can have any access modifier.
  • final Methods: An abstract class can have final methods, which cannot be overridden by subclasses.

Use Cases:

  • Code Reusability: Provides a common base for related classes, allowing subclasses to share common implemented methods and fields.
  • Template Method Pattern: Often used to implement the template method design pattern, where a skeleton of an algorithm is defined in the abstract class, and concrete steps are left for subclasses to implement.
  • Hierarchy of Related Objects: Best suited when there is an "is-a" relationship and you want to provide common state and behavior to a group of tightly related objects.
  • Version Control: Easier to evolve than interfaces without breaking existing implementations, as you can add new concrete methods without forcing subclasses to implement them.

Example:

abstract class Vehicle {
String brand;
int year;

public Vehicle(String brand, int year) { // Constructor
this.brand = brand;
this.year = year;
}

public void displayInfo() { // Concrete method
System.out.println("Brand: " + brand + ", Year: " + year);
}

public abstract void start(); // Abstract method
public abstract void stop();
}

class Car extends Vehicle {
public Car(String brand, int year) {
super(brand, year);
}

@Override
public void start() {
System.out.println("Car starts with a key.");
}

@Override
public void stop() {
System.out.println("Car stops by pressing brake.");
}
}

Key Differences Summarized

FeatureInterfaceAbstract Class
Type of MembersOnly public static final fields. Abstract, default, static, and private methods.Any type of fields (static, non-static, final, non-final) with any access modifier. Abstract and concrete methods.
AbstractionHistorically, 100% abstract. Now, can have concrete default and static methods.Can be 0% to 100% abstract (can have zero or more abstract methods).
MethodsAbstract methods are implicitly public abstract. Can have default, static, private methods.Abstract methods are explicitly abstract. Can have concrete methods with any access modifier.
ConstructorsCannot have constructors.Can have constructors.
InheritanceA class implements interfaces. Supports multiple inheritance of type. An interface extends other interfaces.A class extends an abstract class. Supports single inheritance only.
"Is-a" vs "Can-do"Defines a "can-do" ability or a contract.Defines an "is-a" relationship or a common base.
Keywordsinterface, implements, extendsabstract, class, extends, implements
Final MethodsMethods can't be final (but default and static methods are implicitly not meant for overriding by subclasses directly).Can have final methods, which cannot be overridden.

When to Choose Which

  • Choose an Interface when:

    • You want to define a contract for what classes can do, regardless of their position in the inheritance hierarchy.
    • You need to achieve multiple inheritance of type.
    • You want to promote loose coupling between components.
    • You are defining an API or a set of behaviors that unrelated classes might implement.
  • Choose an Abstract Class when:

    • You want to provide a common base implementation for related classes, sharing code and state.
    • You have methods that should be implemented by subclasses, but also methods with a default implementation that can be inherited.
    • You need to define common fields (variables) that subclasses will share.
    • You want to enforce a specific hierarchy for a set of classes.
    • You need to provide constructors for subclasses.

In essence, interfaces define what an object can do (its contract/behavior), while abstract classes define what an object is (its type and shared implementation). Often, complex designs might utilize a combination of both to achieve robust and extensible architectures.