Creo que el razonamiento es algo como esto:
Digamos que usted tiene un método que acepta un rectángulo y ajusta su anchura:
public void SetWidth(Rectangle rect, int width)
{
rect.Width = width;
}
Cabe perfectamente razonable, dado que un rectángulo es , para suponer que esta prueba pasaría:
Rectangle rect = new Rectangle(50, 20); // width, height
SetWidth(rect, 100);
Assert.AreEqual(20, rect.Height);
... porque cambiar el ancho de un rectángulo no afecta su altura.
Sin embargo, supongamos que ha obtenido una nueva clase Cuadrado de Rectángulo. Por definición, un cuadrado tiene alto y ancho siempre iguales. Vamos a tratar que prueba de nuevo:
Rectangle rect = new Square(20); // both width and height
SetWidth(rect, 100);
Assert.AreEqual(20, rect.Height);
Esa prueba fallará, ya que el establecimiento de la anchura de un cuadrado a 100 también cambiará su altura.
Por lo tanto, el principio de sustitución de Liskov se infringe derivando Square from Rectangle.
La regla "is-a" tiene sentido en el "mundo real" (un cuadrado es definitivamente un tipo de rectángulo), pero no siempre en el mundo del diseño de software.
Editar
Para responder a su pregunta, el diseño correcto probablemente debería ser que tanto rectángulo y de la plaza se derivan de un "Polígono" común o una clase de "Forma", que no hace cumplir las normas relativas a la anchura o altura .
Segundo ejemplo, si el assert está probando 50? Por cierto, en el "mundo real" un cuadrado no es mutable (se dibuja en una página) o puede dejar de ser un cuadrado cuando se aplica una fuerza (está hecho de caucho), IOW en el mundo real un objeto puede cambie el tipo dinámicamente, algo que no modelamos muy bien en los lenguajes de programación. – AnthonyWJones
Vaya bien visto en el segundo ejemplo. La prueba es correcta: el parámetro ctor es incorrecto. ¡Error de herencia de portapapeles! Lo arreglaré ahora. –