1 min read

Liskov Substitution Principle

The Liskov Substitution Principle (LSP) is a principle in object-oriented programming that suggests that objects of a superclass should be replaceable with objects of its subclasses. That means  if a piece of code is designed to work with objects of a certain base class, it should also work correctly with objects of any derived class without any modifications.

To adhere to the LSP, the derived class must satisfy the following conditions:

  1. The derived class should provide the same methods and behaviour as the base class and should not remove or change any preconditions or postconditions of those methods.
  2. The derived class can extend the functionality of the base class, but it should not modify or override any behaviour that is crucial for the correctness of the base class.
  3. The derived class should not introduce any new exceptions or throw exceptions that are not expected by the base class.

Example:

class Shape
  def area
    raise NotImplementedError, "Subclasses must implement the 'area' method"
  end
end

class Rectangle < Shape
  attr_accessor :width, :height

  def area
    width * height
  end
end

class Square < Shape
  attr_accessor :side_length

  def area
    side_length**2
  end
end

class Circle < Shape
  attr_accessor :radius

  def area
    Math::PI * radius**2
  end
end

In this example, the Shape class is the base class that defines a contract with a method called area. It raises a NotImplementedError to indicate that subclasses must implement their own area method.

The Rectangle, Square, and Circle classes are derived from Shape and provide their own implementation of the area method, specific to each shape. They fulfil the contract defined by the base class.

def print_area(shape)
  puts "Area: #{shape.area}"
end

rectangle = Rectangle.new
rectangle.width = 5
rectangle.height = 3

square = Square.new
square.side_length = 4

circle = Circle.new
circle.radius = 2

print_area(rectangle) # Output: Area: 15
print_area(square)    # Output: Area: 16
print_area(circle)    # Output: Area: 12.566370614359172

In this example, the print_area method takes a Shape object as an argument and calls its area method. It works correctly with objects of the Rectangle, Square, and Circle classes without needing to modify the method.

The Liskov Substitution Principle is observed because objects of the derived classes (Rectangle, Square, and Circle) can be substituted for objects of the base class (Shape) without affecting the correctness of the program. This allows for polymorphism and writing code that is more flexible and extensible.