DEV Community

Fatima Alam
Fatima Alam

Posted on

Liskov Substitution Principle

If the Parent class has a method which is not required in a new Child class in this case our design becomes unscalable.
There is a need to remove this method from this Parent Class and create a Child class which inherits from this Parent Class and all the present Child Classes now are sub Child of this Child Class now.
For eg ->
🚗 Before (LSP Violation)

Here, Vehicle has hasEngine(). But Bicycle doesn’t really have an engine, so overriding it with null breaks LSP.

// Base class
class Vehicle {
    public int numberOfWheels() {
        return 0;
    }

    public Boolean hasEngine() {
        return true;
    }
}

// Car inherits Vehicle
class Car extends Vehicle {
    @Override
    public int numberOfWheels() {
        return 4;
    }

    @Override
    public Boolean hasEngine() {
        return true;
    }
}

// Motorcycle inherits Vehicle
class Motorcycle extends Vehicle {
    @Override
    public int numberOfWheels() {
        return 2;
    }

    @Override
    public Boolean hasEngine() {
        return true;
    }
}

// 🚲 Bicycle incorrectly overrides hasEngine
class Bicycle extends Vehicle {
    @Override
    public int numberOfWheels() {
        return 2;
    }

    @Override
    public Boolean hasEngine() {
        return null; // ❌ Problem: breaks LSP
    }
}
Enter fullscreen mode Exit fullscreen mode

If a client expects every Vehicle to have a meaningful hasEngine(), Bicycle breaks that expectation.

✅ After (Refactored to Respect LSP)

We separate Engine-related vehicles into another class.
Now, Bicycle does not need to lie about hasEngine().

// Base Vehicle class
class Vehicle {
    public int numberOfWheels() {
        return 0;
    }
}

// Engine-based vehicles
class EngineVehicle extends Vehicle {
    public boolean hasEngine() {
        return true;
    }
}

// Car inherits EngineVehicle
class Car extends EngineVehicle {
    @Override
    public int numberOfWheels() {
        return 4;
    }
}

// Motorcycle inherits EngineVehicle
class Motorcycle extends EngineVehicle {
    @Override
    public int numberOfWheels() {
        return 2;
    }
}

// Bicycle inherits Vehicle (no engine here)
class Bicycle extends Vehicle {
    @Override
    public int numberOfWheels() {
        return 2;
    }
}
Enter fullscreen mode Exit fullscreen mode

🔑 Key Difference

Before: All Vehicles were forced to define hasEngine(), but Bicycle violated LSP.

After: We introduced EngineVehicle, so only engine-based vehicles must define engine-related behavior.

Car and Motorcycle → extend EngineVehicle

Bicycle → extends plain Vehicle

Top comments (0)