Introduction

The Liskov Substitution Principle states that if you have a base class (in this case, Bike) and derived classes (MotorCycle and Bicycle), the derived classes should be able to replace the base class without causing issues.

General

If you have a family of objects where one is the main type and others are variations, you should be able to use the variations wherever you use the main type, without things going haywire.” It’s all about making sure that new types don’t mess up how the old type worked.

Bike.java

interface Bike{
	void turnOnEngine();
	void accelerate();
}

MotorCycle.java

class MotorCycle implements Bike{
	boolean isEngineOn;
	int speed;
	
	@Override
	public void turnOnEngine(){
		//turn on engine
		isEngineOn = true;
	}
	
	@Override
	public int accelerate(){
		//increase the speed
		speed = speed + 10;
	}
}

Bicycle.java

class Bicycle implements Bike{
	boolean isEngineOn;
	int speed;
	
	@Override
	public void turnOnEngine(){
		throw new AssertionError("there is no engine");
	}
	
	@Override
	public int accelerate(){
		//increase the speed
		speed = speed + 10;
	}
}

In the case of Bicycle, turnOnEngine() is implemented to throw an error because bicycles don’t have engines. This implementation contradicts the behavior expected from the base interface.

In a nutshell, the Liskov Substitution Principle encourages you to ensure that derived classes can be used interchangeably with the base class, following the same behavior. In this example, the Bicycle class breaks this principle by providing behavior that is not consistent with the expected behavior defined in the base class (Bike) interface.

classDiagram
    EngineVehicle <|-- MotorCycle
    NonEngineVehicle <|-- Bicycle
    
    class EngineVehicle {
        <<interface>>
        +turnOnEngine()
        +accelerate()
    }
    
    class NonEngineVehicle {
        <<interface>>
        +accelerate()
    }
    
    class MotorCycle {
        +boolean isEngineOn
        +int speed
        +turnOnEngine()
        +accelerate()
    }
    
    class Bicycle {
        +int speed
        +accelerate()
    }