¿Qué es?
El Liskov Substitution Principle dice que si B es una subclase de A, cualquier código que funcione con A debe seguir funcionando igual de bien si en su lugar se le pasa un B. Si una subclase cambia el comportamiento esperado (lanza errores donde no se esperaban, ignora parámetros, devuelve otra cosa), rompe el contrato y viola LSP.
Antes: la subclase rompe el contrato
class Rectangle {
constructor(protected width: number, protected height: number) {}
setWidth(width: number): void {
this.width = width;
}
setHeight(height: number): void {
this.height = height;
}
getArea(): number {
return this.width * this.height;
}
}
// Un cuadrado "es un" rectángulo... pero no se comporta igual
class Square extends Rectangle {
setWidth(width: number): void {
this.width = width;
this.height = width; // efecto colateral inesperado
}
setHeight(height: number): void {
this.width = height;
this.height = height; // efecto colateral inesperado
}
}
function testArea(rect: Rectangle) {
rect.setWidth(5);
rect.setHeight(4);
console.log(rect.getArea()); // se espera 20
}
testArea(new Rectangle(0, 0)); // 20 ✅
testArea(new Square(0, 0)); // 16 ❌ — rompe la expectativaSquare hereda de Rectangle pero no puede sustituirlo: cualquier código escrito para Rectangle deja de dar el resultado esperado cuando recibe un Square.
Después: modelar el contrato correcto
interface Shape {
getArea(): number;
}
class Rectangle implements Shape {
constructor(private width: number, private height: number) {}
getArea(): number {
return this.width * this.height;
}
}
class Square implements Shape {
constructor(private side: number) {}
getArea(): number {
return this.side ** 2;
}
}
function printArea(shape: Shape) {
console.log(shape.getArea());
}
printArea(new Rectangle(5, 4)); // 20 ✅
printArea(new Square(4)); // 16 ✅ — comportamiento consistente con su propio contratoEn vez de forzar una relación de herencia que no reflejaba la realidad, Rectangle y Square pasan a implementar una interfaz común (Shape) con un contrato mínimo que ambas cumplen sin sorpresas.