Difference Between Abstract Class and Interface in Java

1. Introduction

In Java, abstract classes and interfaces are used to achieve abstraction, which is one of the four pillars of object-oriented programming. An abstract class can define both complete (concrete) and incomplete (abstract) methods and can have state (member variables). An interface, traditionally, is a pure abstraction that cannot have any method implementations until Java 8; after which default methods in interfaces were introduced.

2. Key Points

1. abstract classes can have both abstract methods (without a body) and methods with implementation.

2. interfaces can only have abstract methods, with the exception of default methods and static methods in Java 8 and beyond.

3. A class can implement multiple interfaces but can only extend one abstract class.

4. abstract classes can maintain state through member variables, but interfaces cannot, although they can have static final variables.

3. Differences

Abstract Class Interface
It can contain abstract methods (without bodies) and concrete methods (with implementations). Before Java 8, interfaces could only contain abstract methods. Since Java 8, interfaces can also contain default and static methods with implementations.
Supports public, protected, and private visibility for methods and fields. Methods are implicitly public, and fields are public, static, and final.
It can declare fields that are not final and static, and it can also include non-public fields. All fields are implicitly public, static, and final, and all methods are public.
A class can extend only one abstract class due to Java's single inheritance model. A class can implement multiple interfaces, supporting multiple inheritance.
Constructors can be defined in abstract classes. Interfaces cannot have constructors.
Used when subclasses share many common methods or fields that can be defined or implemented once in the abstract class. Used to define a contract for subclasses to implement, especially when they share no code but must implement specific methods.
Abstract classes are chosen when future changes to the base class might not impact or require changes to subclasses. Interfaces are preferred when it is unlikely that additional non-abstract methods or fields will be needed in the future.
An abstract class can provide a common base implementation for multiple related classes. Interfaces are better suited for providing common capability without enforcing a class hierarchy.

4. Example

// Define an abstract class
abstract class Vehicle {
    protected String brand; // Abstract class can have member variables

    // Abstract class can have a constructor
    public Vehicle(String brand) {
        this.brand = brand;
    }

    // Abstract class can have concrete methods
    public void start() {
        System.out.println("This " + brand + " is starting.");
    }

    // Abstract class can have abstract methods
    public abstract void honk();
}

// Define an interface
interface Flyable {
    // Interfaces can have abstract methods
    void fly();

    // Interfaces can have default methods (Java 8+)
    default void land() {
        System.out.println("I am landing.");
    }
}

// A class that extends the abstract class and implements the interface
class FlyingCar extends Vehicle implements Flyable {

    public FlyingCar(String brand) {
        super(brand);
    }

    // Implement the abstract method from Vehicle
    public void honk() {
        System.out.println("This " + brand + " is honking.");
    }

    // Implement all abstract methods from Flyable
    public void fly() {
        System.out.println("This " + brand + " is flying.");
    }
}

public class Main {
    public static void main(String[] args) {
        FlyingCar car = new FlyingCar("Terrafugia");

        // Using the method from abstract class
        car.start();

        // Using the method from interface
        car.fly();

        // Using the default method from interface
        car.land();

        // Using the method implemented in the subclass
        car.honk();
    }
}

Output:

This Terrafugia is starting.
This Terrafugia is flying.
I am landing.
This Terrafugia is honking.

Explanation:

1. Vehicle is an abstract class that has a member variable, a constructor, a concrete method start(), and an abstract method honk().

2. Flyable is an interface with an abstract method fly() and a default method land().

3. FlyingCar extends Vehicle and implements Flyable, providing implementations for the abstract methods.

4. The main method creates an instance of FlyingCar and calls its methods to demonstrate the functionalities inherited

Comments