Liskov Substitution Principle

Open In Colab

2.3. Liskov Substitution Principle#

El Principio de Sustitución de Liskov (Liskov Substitution Principle - LSP) es uno de los cinco principios SOLID del diseño de software. Fue propuesto por Barbara Liskov en 1987 y establece que los objetos de un programa deberían ser reemplazables por instancias de sus subtipos sin afectar la corrección del programa.

2.3.1. Definición del LSP:#

El principio LSP establece que los objetos de un programa deben poder ser sustituidos por instancias de sus subtipos sin alterar las propiedades del programa, como la corrección y la ejecución exitosa. En otras palabras, una subclase debe poder reemplazar a su clase base sin cambiar el comportamiento esperado del programa. Esto implica que los subtipos deben seguir cumpliendo con las mismas precondiciones y postcondiciones que sus tipos base.

2.3.2. Ejemplo del LSP:#

Supongamos que tenemos una jerarquía de clases que representan diferentes tipos de aves, como Bird, Duck y Penguin. Siguiendo el principio LSP, todas las subclases deben poder ser utilizadas en lugar de su clase base (Bird) sin causar efectos secundarios.

class Bird:
    def fly(self):
        pass

class Duck(Bird):
    def fly(self):
        print("Duck flying")

class Penguin(Bird):
    def fly(self):
        raise NotImplementedError("Penguins can't fly")

# Función que interactúa con objetos de tipo Bird
def bird_interaction(bird):
    bird.fly()
# Uso del principio LSP
duck = Duck()
bird_interaction(duck)      # Duck flying
Duck flying
penguin = Penguin()
bird_interaction(penguin)   # NotImplementedError: Penguins can't fly
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[3], line 2
      1 penguin = Penguin()
----> 2 bird_interaction(penguin)   # NotImplementedError: Penguins can't fly

Cell In[1], line 15, in bird_interaction(bird)
     14 def bird_interaction(bird):
---> 15     bird.fly()

Cell In[1], line 11, in Penguin.fly(self)
     10 def fly(self):
---> 11     raise NotImplementedError("Penguins can't fly")

NotImplementedError: Penguins can't fly

En este ejemplo, tanto Duck como Penguin son subtipos de Bird. Sin embargo, Penguin no puede volar, por lo que su implementación de fly() lanza una excepción. A pesar de que Penguin no puede volar, sigue siendo una subclase válida de Bird y puede ser utilizada en lugar de Bird en la función bird_interaction(). Esto demuestra el cumplimiento del principio LSP, ya que el comportamiento del programa no se ve afectado por la sustitución de objetos de tipo Bird con sus subtipos.