27 Oct 2023



Intermediate

The Liskov Substitution Principle (LSP) states that "objects of a derived class should be able to replace objects of the base class without affecting the correctness of the program."

In simpler terms, it means that if you have a class (the base or parent class) and another class that inherits from it (the derived or child class), you should be able to use objects of the child class wherever you use objects of the parent class, and the program should still work correctly.

The Liskov Substitution Principle (LSP) is a fundamental concept in object-oriented programming, and it's used to ensure that derived classes can be used interchangeably with their base classes. Here are some real-world examples of the Liskov Substitution Principle:

  1. Shape Hierarchy:
    • Base Class: "Shape"
    • Derived Classes: "Circle," "Rectangle," "Triangle"
    • Real-world example: You can use a "Circle" or a "Rectangle" wherever you expect a "Shape," because they are all shapes with common properties like area and perimeter.
class Shape
    method CalculateArea()
    method CalculatePerimeter()

class Circle extends Shape
    method CalculateArea()
    method CalculatePerimeter()

class Rectangle extends Shape
    method CalculateArea()
    method CalculatePerimeter()

class Triangle extends Shape
    method CalculateArea()
    method CalculatePerimeter()
Shape someShape = new Circle();
Shape anotherShape = new Rectangle();
Shape oneMoreShape = new Triangle();

someShape.CalculateArea();  // Calls the Circle's CalculateArea method.
anotherShape.CalculateArea();    // Calls the Rectangle's CalculateArea method.
oneMoreShape.CalculateArea();     // Calls the Triangle's CalculateArea method.

You can see that even though we're using the base class Shape to reference objects of derived classes Circle, Rectangle, and Triangle, the correct methods for calculating areas are called based on the actual object type. This adheres to the Liskov Substitution Principle as it allows objects of derived classes to replace objects of the base class without affecting the correctness of the program.

  1. Animal Hierarchy:
    • Base Class: "Animal"
    • Derived Classes: "Dog," "Cat," "Bird"
    • Real-world example: If you have a function that accepts an "Animal" object, you can pass a "Dog," "Cat," or "Bird" object, because they all share common behaviors and properties as animals.
class Animal
    method MakeSound()
    method Eat()
    property Name

class Dog extends Animal
    method MakeSound()
    method Eat()

class Cat extends Animal
    method MakeSound()
    method Eat()

class Bird extends Animal
    method MakeSound()
    method Eat()

Using OOP, you can replace an object of the base class Animal with objects of derived classes Dog, Cat, or Bird without affecting the correctness of the program:

Animal myPet = new Dog();
Animal aCat = new Cat();
Animal aBird = new Bird();

myPet.MakeSound();   // Calls the Dog's MakeSound method.
aCat.Eat();          // Calls the Cat's Eat method.
aBird.MakeSound();   // Calls the Bird's MakeSound method.
  1. File Handling:
    • Base Class: "File"
    • Derived Classes: "TextFile," "ImageFile," "AudioFile"
    • Real-world example: You can write code that works with "File" objects and handle different types of files like "TextFile," "ImageFile," and "AudioFile" interchangeably.
class File
    method Read()
    method Write()

class TextFile extends File
    method Read()
    method Write()

class ImageFile extends File
    method Read()
    method Write()

class AudioFile extends File
    method Read()
    method Write()

In OOP, you can replace a File object with a TextFile, ImageFile, or AudioFile object:

File anyFile = new TextFile();
File anImage = new ImageFile();
File someAudio = new AudioFile();

anyFile.Read();      // Calls the TextFile's Read method.
anImage.Write();     // Calls the ImageFile's Write method.
someAudio.Read();    // Calls the AudioFile's Read method.
  1. Vehicle Hierarchy:
    • Base Class: "Vehicle"
    • Derived Classes: "Car," "Bicycle," "Motorcycle"
    • Real-world example: If you have a function that takes a "Vehicle" as a parameter, you should be able to pass any of the derived classes like "Car," "Bicycle," or "Motorcycle" because they are all types of vehicles.
class Vehicle
    method Start()
    method Stop()

class Car extends Vehicle
    method Start()
    method Stop()

class Bicycle extends Vehicle
    method Start()
    method Stop()

class Motorcycle extends Vehicle
    method Start()
    method Stop()

Using OOP, you can replace a Vehicle object with a Car, Bicycle, or Motorcycle object:

Vehicle myCar = new Car();
Vehicle aBicycle = new Bicycle();
Vehicle aMotorcycle = new Motorcycle();

myCar.Start();         // Calls the Car's Start method.
aBicycle.Stop();       // Calls the Bicycle's Stop method.
aMotorcycle.Start();   // Calls the Motorcycle's Start method.
  1. Collection Classes:
    • Base Class: "List"
    • Derived Classes: "ArrayList," "LinkedList"
    • Real-world example: You can use a "List" interface or class to work with lists, and you can interchangeably use "ArrayList" or "LinkedList" to store and manipulate data in a list structure.
class List
    method Add(item)
    method Remove(item)
    method Get(index)

class ArrayList extends List
    method Add(item)
    method Remove(item)
    method Get(index)

class LinkedList extends List
    method Add(item)
    method Remove(item)
    method Get(index)

In OOP, you can replace a List object with an ArrayList or LinkedList object:

List myList = new ArrayList();
List yourList = new LinkedList();

myList.Add(item1);     // Calls the ArrayList's Add method.
yourList.Get(index);   // Calls the LinkedList's Get method.
  1. Employee Hierarchy:
    • Base Class: "Employee"
    • Derived Classes: "Manager," "Engineer," "Salesperson"
    • Real-world example: When working with an employee management system, you should be able to treat "Manager," "Engineer," and "Salesperson" objects as "Employee" objects, allowing you to manage employees generically.
class Employee
    method Work()
    method GetSalary()

class Manager extends Employee
    method Work()
    method GetSalary()

class Engineer extends Employee
    method Work()
    method GetSalary()

class Salesperson extends Employee
    method Work()
    method GetSalary()

You can replace an Employee object with a Manager, Engineer, or Salesperson object:

Employee anyEmployee = new Manager();
Employee anEngineer = new Engineer();
Employee aSalesperson = new Salesperson();

anyEmployee.Work();         // Calls the Manager's Work method.
anEngineer.GetSalary();     // Calls the Engineer's GetSalary method.
aSalesperson.Work();        // Calls the Salesperson's Work method.

In each of these examples, objects of derived classes can replace objects of the base class without affecting the correctness of the program, adhering to the Liskov Substitution Principle in object-oriented programming.

solid-principles
liskov-substitution-principle