Curso Principios SOLID - 3. Principio de Sustitución de Liskov

La L de SOLID representa el principio de sustitución de Liskov y su nombre viene porque Barbara Liskov fue la primera persona en hablar de él. Este principio establece que si en nuestro código tenemos una clase y la extendemos, tenemos que poder utilizar cualquiera de las clases hijas y que el programa siga siendo válido, es decir, que cuando extendemos una clase padre con una clase hija, el comportamiento de la clase padre no debe modificarse.

Ejemplo práctico

Las clases hijas nunca deberían romper la clase padre, es decir, que una subclase debe sobrescribir una clase padre sin romper su funcionalidad. Para explicar esto vamos a hacer un ejemplo muy típico de violación del principio de sustitución de Liskov.

<?php
class Rectangle
{
    protected $width;
    protected $height;

    public function setWidth($width)
    {
        $this->width = $width;
    }

    public function setHeight($height)
    {
        $this->height = $height;
    }

    public function area()
    {
        return $this->width * $this->height;
    }
}

class Square extends Rectangle
{
    public function setWidth($width)
    {
        parent::setWidth($width);
        parent::setHeight($width);
    }

    public function setHeight($height)
    {
        parent::setWidth($height);
        parent::setHeight($height);
    }
}

class Tester
{
    public static function testRectangle()
    {
        $rectangle = new Rectangle();
        $rectangle->setWidth(8);
        $rectangle->setHeight(4);

        if ($rectangle->area() !== 32) {
            throw new Exception("The area is incorrect");
        }

        echo "Everything correct" . PHP_EOL;
    }

    public static function testSquare()
    {
        $rectangle = new Square();
        $rectangle->setWidth(8);
        $rectangle->setWidth(4);

        if ($rectangle->area() !== 32) {
            throw new Exception("The area is incorrect");
        }

        echo "Everything correct" . PHP_EOL;
    }
}

En este caso hemos creado una clase Rectangle que ha sido extendida creando la clase Square, pero esta última clase altera el comportamiento de la clase padre porque el método setHeight no solo especifica la altura sino también el ancho del cuadrado, y viceversa.

Además de esto, este principio desmiente esa idea que existe en la programación orientada a objetos que dice que podemos tratar objeto de la vida real como si fuera un objeto.