0% completed
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.
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.
The Vehicle class provides basic vehicle functionality, with refuel() left abstract for subclasses to implement according to their specific fuel or energy requirements.
The Car class inherits from Vehicle and implements the refuel() method specific to gasoline-powered cars.
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.
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.
Let’s test the system by creating instances of both Car and ElectricCar and see how they behave.
With this new design:
Car and ElectricCar inherit from Vehicle, and they can be used interchangeably without breaking the program.Car and ElectricCar) implements its own version of the refuel() method. For the electric car, refuel() calls the specific recharge() method, maintaining expected behavior without breaking the contract of the Vehicle class.ElectricCar can replace Car without causing issues.When Subclasses Can’t Implement Parent’s Behavior: If a subclass can’t fully follow the parent’s contract (e.g., ElectricCar refueling), it’s time to rethink the hierarchy.
When Subclasses Behave Too Differently: If subclasses have vastly different behaviors, a more general parent class may be needed to avoid forcing inappropriate methods on subclasses.
When Conditionals Increase: If you're adding too many conditionals in subclasses, it's a sign that the hierarchy isn’t flexible enough and needs refactoring.
Breaking the hierarchy is useful when you notice these patterns, helping you build more flexible and maintainable systems.
.....
.....
.....