Professional Documents
Culture Documents
de Liskov
(LSP)
Liskov Substitution
Principle
Sub
Super
Donde quiera que se usaba la
superclase, se puede usar la
subclase
As que...
Para respetar el LSP:
La subclase no puede prohibir algo que se permita en
la superclase.
Los mtodos de la subclase deben entregar el mismo
tipo (o uno derivado) como resultados.
Los mtodos de la subclase deben recibir el mismo tipo
(o uno derivado) de parmetros.
Donde quiera que se usaba una referencia a un objeto
de la superclase, se debe poder usar una a un objeto
de la subclase y todo debe funcionar igual.
Ejemplo: Ave
class Ave {
public void volar(){}
public void comer(){}
}
Ejemplo: subclases
class Cuervo extends Ave {}
class Guajolote extends Ave {
volar(){
throw new
UnsupportedOperationException();
}
}
Ejemplo: prueba
hagamosQueVuelen
static void hagamosQueVuelen(List<Ave>
lstaves){
for (Ave pajaro : lstaves) {
pajaro.vuela();
}
}
} // Fin de AveTest
Por qu no jala
Cmo se resuelve?
Factorizando:
Lo comn a todas las instancias de Ave es que
comen. As que Ave slo come.
De ella derivan dos subclases: las que vuelan y
las que no.
Cuervo es subclase de la las que vuelan.
Guajolote es subclase de las que no vuelan.
Es decir...
class Ave{
public void comer(){}
}
class AveVoladora extends Ave {
public void vuela()()
}
class AveNoVoladora extends Ave{}
Otro
class
protected
protected
public
void
m_width
}
public
void
m_height
}
public
int
return
}
Rectangle
int
int
setWidth(int
=
{
m_width;
m_height;
width)
{
width;
setHeight(int
=
height)
getWidth()
{
height;
{
m_width;
Otro
class
public
return
}
public
return
}
}
//
int
Rectangle
lo
getHeight()
int
m_width
getArea()
*
{
anterior
{
m_height;
{
m_height;
Cuadrado
class
Square
public
void
m_width
m_height
}
public
void
m_width
m_height
}
}
extends
setWidth(int
=
=
Rectangle
width)
{
{
width;
width;
setHeight(int
=
=
height)
{
height;
height;
Prueba
class
LspTest
{
private static Rectangle getNewRectangle()
{
// it can be an object returned by some factory ...
return
new
Square();
}
Prueba
public
static
void
main
(String
args[])
{
Rectangle
r
=
LspTest.getNewRectangle();
r.setWidth(5);
r.setHeight(10);
// user knows that r it's a rectangle.
// It assumes that he's able to set
// the width and height as for the base class
System.out.println(r.getArea());
// now he's surprised to see that the
// area is 100 instead of 50.
}
} // Fin de Prueba
Qu sali mal?
Todo cuadrado ES UN rectngulo, qu no?
Es que la relacin ES UN es un poco menos
superficial.
Lo de ES UN debe estar referido al
COMPORTAMIENTO, no slo a los atributos.
Un cuadrado es un caso particular de rectngulo, pero
NO puedo usarlo siempre que usaba un rectngulo.
Si tengo que modificar el programa para adecuarlo
cuando uso una subclase particular, estoy violando el
principio Open/Close, que generaliza el LSP.