Raheel Parekh

Sep 10, 2025 • 4 min read

Interfaces vs Abstract Classes in Java: Simple Guide with Real-World Examples


🔑 What is an Interface in Java?

Think of an interface as a contract.

It says:
👉 “If you want to be this type, you must do these things.”

  • It only defines what needs to be done, not how.

  • Classes that use it must provide their own implementation.

  • A class can implement multiple interfaces (like having multiple roles).

Example:

interface Animal {
 void makeSound();
 void move();
}

class Dog implements Animal {
 public void makeSound() {
 System.out.println("Woof!");
 }

 public void move() {
 System.out.println("Running on four legs...");
 }
}

Here:

  • Animal is the contract.

  • Dog promises to follow the contract by defining both makeSound() and move().


🔑 What is an Abstract Class in Java?

An abstract class is like a half-built house.

It provides:

  • Some ready-made parts (concrete methods).

  • Some empty rooms you must finish (abstract methods).

  • You cannot create an object of an abstract class directly.

Example:

abstract class Animal {
 public void eat() {
 System.out.println("Eating food..."); 
 }

 public abstract void makeSound();
}

class Cat extends Animal {
 public void makeSound() {
 System.out.println("Meow!");
 }
}

Here:

  • Animal already has an eat() method for all animals. Every animal eats so you dont need to rewrite eat method for Animals.

  • But it leaves makeSound() blank, so each subclass (like Cat, Dog) fills it in differently.


📝 When to Use Interface vs Abstract Class?

Here’s the simple rule of thumb 👇

  • Use Interface when:

    • You want to define a role/capability.

    • Example: Runnable (a class "can run"), Comparable (a class "can compare").

    • Classes may be completely unrelated but still share the same behavior.

  • Use Abstract Class when:

    • You want to create a base class with some shared implementation.

    • Example: All animals eat and sleep the same way, but sound is different.

    • Classes are in the same family (like AnimalDog, Cat).


🌍 Real-World Example: Vehicles

Imagine we are building a transport app like Uber 🚖.

We have different types of vehicles: Car, Bike, Truck, ElectricCar.

🚦 Interface Example: "Drivable"

Here, not all vehicles are the same (a bike is very different from a truck).
But they all share a common ability: they can drive.

So, we make an interface:

interface Drivable {
 void drive();
}

Then each vehicle defines how it drives:

class Car implements Drivable {
 public void drive() {
 System.out.println("Driving a car on the road...");
 }
}

class Bike implements Drivable {
 public void drive() {
 System.out.println("Riding a bike...");
 }
}

class Truck implements Drivable {
 public void drive() {
 System.out.println("Driving a heavy truck...");
 }
}

👉 Here, the interface ensures all vehicles can "drive,"
but each vehicle has its own unique driving style.


🚗 Abstract Class Example: "Vehicle"

Now, think deeper:

  • All vehicles have wheels, fuel type, and a start() method.

  • Instead of repeating this code in every class, we create an abstract class.

abstract class Vehicle {
 String fuelType;

 public void start() { // common implementation
 System.out.println("Starting the vehicle...");
 }

 public abstract void refuel(); // must be defined differently
}

Concrete classes extend it:

class Car extends Vehicle {
 public Car() {
 fuelType = "Petrol";
 }

 @Override
 public void refuel() {
 System.out.println("Refueling the car with " + fuelType);
 }
}

class ElectricCar extends Vehicle {
 public ElectricCar() {
 fuelType = "Electric";
 }

 @Override
 public void refuel() {
 System.out.println("Charging the electric car...");
 }
}

👉 Here, the abstract class gives a common base (start() method, fuelType variable).
But still enforces subclasses to define their own refuel logic.


✅ Why This Works

  • Interface (Drivable) = Focuses on the ability ("This thing can drive").

  • Abstract Class (Vehicle) = Focuses on the blueprint with shared logic (all vehicles start the same way, but refueling differs).


⚡ Analogy

Think of it like this:

  • Interface → A driving license 🚦. Anyone who has it can drive, but how they drive depends on the person.

  • Abstract Class → A base car model 🚗. All cars have wheels and engines, but each brand customizes features differently.


✅ Key Takeaways

  • Interface = Only contract, no common implementation.

  • Abstract Class = Contract + shared code.

  • Use interfaces for capabilities.

  • Use abstract classes for related objects with shared behavior.


❓ FAQ: Interfaces vs Abstract Classes

Q1: Can a class use both?
👉 Yes! A class can extend an abstract class and implement multiple interfaces.

Q2: Which one should I prefer in modern Java?
👉 Prefer interfaces for flexibility. Use abstract classes when you need shared code or state.

Q3: Why can’t we just always use interfaces?
👉 Because interfaces don’t hold shared state (like variables) or full method implementations (except default methods). Abstract classes handle that better.


✨ That’s it! Next time you’re stuck choosing between an interface and an abstract class, just ask yourself:

  • “Do I need only a contract?” → Go with Interface.

  • “Do I need a base class with shared logic?” → Go with Abstract Class.

Join Raheel on Peerlist!

Join amazing folks like Raheel and thousands of other builders on Peerlist.

peerlist.io/

It’s available... this username is available! 😃

Claim your username before it's too late!

This username is already taken, you’re a little late.😐

0

6

0