Skip to content

Java Abstract Classes and Interfaces

Abstraction is one of the four pillars of object-oriented programming. It aims to hide complex implementation details and expose only the necessary functionality to users. In Java, abstraction is primarily achieved through two mechanisms: Abstract Classes and Interfaces.

Abstract Class

An abstract class is a class that cannot be instantiated and serves as a parent class (base class) for other classes. It's used to define a general template for a type, which can include some already implemented concrete methods and some abstract methods that must be implemented by subclasses.

  • Use the abstract keyword to declare an abstract class.
  • An abstract class can contain instance variables, constructors, concrete methods (with a body), and abstract methods.
  • Abstract method: Has only a method signature with no body, declared using the abstract keyword. Any subclass that inherits an abstract class must implement all of its abstract methods, unless that subclass itself is also an abstract class.
java
// 1. Define an abstract class
abstract class Shape {
    private String color;

    // Abstract classes can have constructors, primarily for subclasses to call
    public Shape(String color) {
        this.color = color;
    }

    // This is a concrete method
    public String getColor() {
        return color;
    }

    // This is an abstract method, no body
    public abstract double getArea();
}

// 2. Create a subclass that extends the abstract class
class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color); // Call parent class constructor
        this.radius = radius;
    }

    // 3. Must implement all abstract methods of the parent class
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

public class Main {
    public static void main(String[] args) {
        // Shape myShape = new Shape("Red"); // Compile error! Cannot instantiate abstract class

        Shape circle = new Circle("Blue", 5.0);
        System.out.println("Color: " + circle.getColor());
        System.out.println("Area: " + circle.getArea());
    }
}

Interface

An interface is a completely abstract reference type that defines a set of methods (behavioral contract). Any class that implements the interface must provide concrete implementations for these methods. Interfaces are a way to achieve multiple inheritance.

  • Use the interface keyword to declare an interface.
  • All methods in an interface are public abstract by default (before Java 8).
  • All variables in an interface are public static final by default (i.e., constants).
  • A class uses the implements keyword to implement one or more interfaces.
java
// 1. Define an interface
interface Playable {
    // public static final is automatically added
    int MAX_VOLUME = 100;

    // public abstract is automatically added
    void play();
    void stop();
}

// 2. Create a class that implements the interface
class MusicPlayer implements Playable {
    @Override
    public void play() {
        System.out.println("Music starts playing...");
    }

    @Override
    public void stop() {
        System.out.println("Music stopped.");
    }
}

// Another class implements the same interface
class VideoPlayer implements Playable {
    @Override
    public void play() {
        System.out.println("Video starts playing...");
    }

    @Override
    public void stop() {
        System.out.println("Video stopped.");
    }
}

Java 8+ Interface Enhancements

Starting from Java 8, interfaces can contain default methods and static methods, adding more flexibility to interfaces.

  • Default method (default method): Allows providing a default implementation for a method in an interface. Classes implementing the interface can use the default version without overriding it.
  • Static method (static method): Belongs to the interface itself and can only be called through the interface name.
java
interface Loggable {
    // Abstract method
    void log(String message);

    // Default method
    default void logInfo(String message) {
        log("[INFO] " + message);
    }

    // Static method
    static String getLoggerName() {
        return "DefaultLogger";
    }
}

Abstract Class vs. Interface

FeatureAbstract ClassInterface
PurposeDefine a general template for a type, achieve code reuseDefine a behavioral contract, specify class capabilities
InheritanceSubclasses use extends keyword, single inheritance in JavaImplementing classes use implements keyword, a class can implement multiple interfaces
Member VariablesCan contain any type of member variables (instance, static)Can only contain public static final constants
ConstructorsCan have constructorsCannot have constructors
MethodsCan contain abstract and concrete methodsOnly abstract methods before Java 8, can have default and static methods after
Relationship"is-a" relationship, emphasizes essence"has-a" or "can-do" relationship, emphasizes capability

When to Use?

  • Use abstract class: When you want to create a base class that contains common code and state shared by subclasses. When there's a clear hierarchy and "is-a" relationship between classes (e.g., Dog is an Animal).
  • Use interface: When you want to define a role or capability that can be possessed by classes at different hierarchies. When you want a class to have multiple unrelated behaviors (e.g., a Bird class can implement both Flyable and Singable interfaces).

Content is for learning and research only.