Knowledge Guide
HomeOO & Low-Level DesignSOLID Principles

Break The Hierarchy for Adhering to LSP

In the previous lesson, we identified the problem where the ElectricCar class violated the Liskov Substitution Principle by failing to implement the refuel() method properly. Now, we will redesign the inheritance hierarchy to follow LSP by introducing a generalized Vehicle class.

Step 1: Create a General Vehicle Class

We’ll begin by creating a generalized Vehicle class, which defines common behaviors shared by all vehicles, such as starting and stopping, and an abstract refuel() method for specific fuel/energy behavior.

java
public abstract class Vehicle {
    public void start() {
        System.out.println("Vehicle is starting");
    }

    public void stop() {
        System.out.println("Vehicle is stopping");
    }

    // Abstract method for fuel/energy behavior
    public abstract void refuel();
}

The Vehicle class provides basic vehicle functionality, with refuel() left abstract for subclasses to implement according to their specific fuel or energy requirements.

Step 2: Refactor Car and ElectricCar Classes

Car Class (Inherits from Vehicle)

java
public class Car extends Vehicle {
    @Override
    public void refuel() {
        System.out.println("Car is refueling with gasoline");
    }
}

The Car class inherits from Vehicle and implements the refuel() method specific to gasoline-powered cars.

ElectricCar Class (Inherits from Vehicle)

In the ElectricCar class, we will introduce a recharge() method for charging the electric car's battery, and we will call this method from the overridden refuel() method.

java
public class ElectricCar extends Vehicle {
    @Override
    public void refuel() {
        // Call recharge() instead of refueling with gasoline
        recharge();
    }

    // Electric cars need to recharge instead of refuel
    private void recharge() {
        System.out.println("Electric car is recharging");
    }
}

Here, the refuel() method in ElectricCar calls the recharge() method, which reflects the real-world behavior of electric cars needing to recharge their batteries instead of refueling with gasoline.

Step 3: Test the New Hierarchy

Let’s test the system by creating instances of both Car and ElectricCar and see how they behave.

java
// Vehicle class (abstract)
abstract class Vehicle {
    public void start() {
        System.out.println("Vehicle is starting");
    }

    public void stop() {
        System.out.println("Vehicle is stopping");
    }

    // Abstract method for fuel/energy behavior
    public abstract void refuel();
}

// Car class (inherits from Vehicle)
class Car extends Vehicle {
    @Override
    public void refuel() {
        System.out.println("Car is refueling with gasoline");
    }
}

// ElectricCar class (inherits from Vehicle)
class ElectricCar extends Vehicle {
    @Override
    public void refuel() {
        // Call recharge() instead of refueling with gasoline
        recharge();
    }

    // Electric cars need to recharge instead of refuel
    private void recharge() {
        System.out.println("Electric car is recharging");
    }
}

// Main class to test the hierarchy
public class Solution {
    public static void main(String[] args) {
        // Using Car object
        Vehicle myCar = new Car();
        myCar.start();
        myCar.refuel(); // Car-specific refueling behavior
        myCar.stop();

        System.out.println();

        // Using ElectricCar object
        Vehicle myElectricCar = new ElectricCar();
        myElectricCar.start();
        myElectricCar.refuel(); // Calls recharge() via refuel()
        myElectricCar.stop();
    }
}

How This Solution Follows LSP?

With this new design:

When to Break the Hierarchy

Breaking the hierarchy is useful when you notice these patterns, helping you build more flexible and maintainable systems.

🤖 Don't fully get this? Learn it with Claude

Stuck on Break The Hierarchy for Adhering to LSP? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Break The Hierarchy for Adhering to LSP** (OO & Low-Level Design) and want to truly understand it. Explain Break The Hierarchy for Adhering to LSP from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Break The Hierarchy for Adhering to LSP** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Break The Hierarchy for Adhering to LSP** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Break The Hierarchy for Adhering to LSP** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes