Subclassing in JavaScript: Understanding and Applying the Liskov Substitution Principle

Post author: Adam VanBuskirk
Adam VanBuskirk
5/9/23 in
Tech
JavaScript

The Liskov Substitution Principle (LSP) is a fundamental principle of object-oriented design that states that objects of a superclass should be able to be replaced by objects of its subclasses without affecting the correctness of the program. In this article, we’ll explore the LSP in JavaScript and provide an example of how it can be violated and then fixed. LSP is one of the principles of SOLID Design Principles.

Violation of the LSP

Let’s take a look at an example of a violation of the LSP:

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  setWidth(width) {
    this.width = width;
  }

  setHeight(height) {
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Square extends Rectangle {
  constructor(size) {
    super(size, size);
  }

  setWidth(width) {
    this.width = width;
    this.height = width;
  }

  setHeight(height) {
    this.width = height;
    this.height = height;
  }
}

In this example, we have a Rectangle class that has a setWidth and setHeight method to set the width and height of the rectangle, and a Square class that extends the Rectangle class. The problem with this code is that a Square object cannot be substituted for a Rectangle object without affecting the correctness of the program. This violates the LSP.

Applying The LSP

To fix this violation of the LSP, we need to create an abstract Shape class that all shapes inherit from, and make sure that any methods or properties that are in the superclass are also in the subclasses. Let’s see how this can be done:

class Shape {
  getArea() {}
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  setWidth(width) {
    this.width = width;
  }

  setHeight(height) {
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Square extends Shape {
  constructor(size) {
    super();
    this.size = size;
  }

  setSize(size) {
    this.size = size;
  }

  getArea() {
    return this.size * this.size;
  }
}

In this example, we have created an abstract Shape class that all shapes inherit from. Both the Rectangle and Square classes have a getArea method that calculates the area of the shape. By doing this, we have made sure that any object of a subclass can be substituted for an object of the superclass without affecting the correctness of the program.

Conclusion

The Liskov Substitution Principle is an essential principle in object-oriented design. By following this principle, we can create code that is more modular, flexible, and maintainable. Violating this principle can lead to code that is difficult to modify and extend and can cause problems down the road. By creating abstract classes and making sure that any methods or properties that are in the superclass are also in the subclasses, we can make our code more modular and extensible.

Sign up today for our weekly newsletter about AI, SEO, and Entrepreneurship

Leave a Reply

Your email address will not be published. Required fields are marked *


Read Next




© 2024 Menyu LLC