All Articles

Liskov Substitution Principle

This article was done using my notes from Vubon Roy & Deekey (2019).

Vubon Roy, (Nov 2, 2019), SOLID Principles with Python Examples, Medium.
Deekey, (Aug 2, 2019),S.O.L.I.D Principles explained in Python with examples.s, Medium.
Wikipedia, (2020), Robert C. Martin.

SOLID principles

SOLID principles are designed to guide Object Oriented Programing. The SOLID principles were defined in the early 2000s by Robert C. Martin.

SOLID stands for

1. Single Responsibility Principle
2. Open and Closed Principle
3. Lisvok Sub situation Principle
4. Interface Segregation Principle
5. Dependency Inversion Principle

Liskov Substitution Principle

The main idea behind Liskov Subtitution Principle is that, for any class, a developer should be able to use any of its subtypes indistinguishably, without even noticing, and therefore without compromising the expected behavior at runtime.

Violation of LSP

Let’s imagine you have a store, and you give a discount of 20% to your favorite customers using this class: When you decide to offer double the 20% discount to VIP customers.

class Vehicle:
   """A demo Vehicle class"""

   def __init__(self, name, speed):
       self.name = name
       self.speed = speed

   def get_name(self):
       """Get vehicle name"""
       return f"The vehicle name {self.name}"

   def get_speed(self):
       """Get vehicle speed"""
       return f"The vehicle speed {self.speed}"

   def engine(self):
       """A vehicle engine"""
       pass

   def start_engine(self):
       """A vehicle engine start"""
       self.engine()


class Car(Vehicle):
   """A demo Car Vehicle class"""
   def start_engine(self):
       pass


class Bicycle(Vehicle):
   """A demo Bicycle Vehicle class"""
   def start_engine(self):
       pass

How does it violate the LSP?

In Bicycle class violates the LSP. Cause in the Vehicle class has an engine method. But naturally, a bicycle has no engine. So we could not start any engine.

Solution

class Vehicle:
   """A demo Vehicle class"""
   def __init__(self, name, speed):
       self.name = name
       self.speed = speed   
       
       def get_name(self):
       """Get vehicle name"""
       return f"The vehicle name {self.name}"   
       
       def get_speed(self):
       """Get vehicle speed"""
       return f"The vehicle speed {self.speed}"

class VehicleWithoutEngine(Vehicle):
   """A demo Vehicle without engine class"""
   def start_moving(self):
      """Moving"""
      raise NotImplemented
      
class VehicleWithEngine(Vehicle):
   """A demo Vehicle engine class"""
   def engine(self):
      """A vehicle engine"""
      pass   
    
    def start_engine(self):
      """A vehicle engine start"""
      self.engine()

class Car(VehicleWithEngine):
   """A demo Car Vehicle class"""
   def start_engine(self):
       pass

class Bicycle(VehicleWithoutEngine):
   """A demo Bicycle Vehicle class""" 
   def start_moving(self):
       pass