Sobes.tech
Junior — Middle

Can you give an example of a situation where the Liskov Substitution Principle is applied to replace one type with another without breaking the program's logic?

sobes.tech AI

Answer from AI

The Liskov Substitution Principle states that objects of a subclass should be interchangeable with objects of the superclass without affecting the correctness of the program.

For example, in iOS: there is a base class Bird with a method fly(). If we create a subclass Penguin that cannot fly, replacing Bird with Penguin would violate the logic if fly() is called somewhere.

The correct approach is to define an interface or base class for flying birds, such as FlyingBird, and implement fly() only there. Then, Penguin inherits from Bird, but not from FlyingBird. This allows replacing FlyingBird objects with subclasses without breaking the logic.

class Bird {
  func eat() {
    print("Bird eats")
  }
}

protocol FlyingBird {
  func fly()
}

class Sparrow: Bird, FlyingBird {
  func fly() {
    print("Sparrow is flying")
  }
}

class Penguin: Bird {
  // Penguin does not fly, does not implement fly()
}

This way, you can safely use FlyingBird objects where flight is needed, without violating the Liskov principle.