PDF de programación - Subtipos e Subclasses

Imágen de pdf Subtipos e Subclasses

Subtipos e Subclassesgráfica de visualizaciones

Publicado el 6 de Septiembre del 2017
1.037 visualizaciones desde el 6 de Septiembre del 2017
181,1 KB
11 paginas
Creado hace 20a (12/12/2003)
Subtipado

Clase 15 del curso 6.170
15 de octubre de 2001



Sumario
1 Subtipos
2 Ejemplo: bicicletas
3 Ejemplo: cuadrado y rectángulo
4 Principio de sustitución
5 Subclases y subtipos Java
6 Interfaces Java

Lecturas necesarias: capítulo 7 del libro Program Development in Java de Bárbara Liskov.

Consulte su libro de texto de Java para obtener detalles sobre este lenguaje como, por
ejemplo, tipos abstractos (no todos los métodos se implementan y ningún objeto se puede
instanciar) y detalles sobre interfaces y modificadores de acceso (public, private, protected,
default). Estos temas no se tratarán en esta clase.

1 Subtipos

Decimos que A es B si todo objeto A es también un objeto B. Por ejemplo, todo automóvil
es un vehículo y toda bicicleta es un vehículo, incluso unos zancos son un vehículo: todo
vehículo es un medio de transporte, así como todo animal de carga. Representamos esta
relación de subconjuntos en un diagrama de dependencia modular:



Esta relación de subconjunto es condición necesaria, pero no suficiente, para una relación
de subtipificación. El tipo A es un subtipo del tipo B cuando la especificación de A implica
la especificación de B. Esto es, cualquier objeto (o clase) que satisfaga la especificación de
A también satisfará la especificación de B, ya que la especificación de B es más débil.

Otra manera de explicar esto es que en cualquier lugar del código, si se espera un objeto B,
es admisible un objeto A. Se garantiza que el código escrito para funcionar con los objetos
B (y para depender de sus propiedades) continua funcionando si se suministran objetos A
en su lugar; además, el comportamiento será el mismo, si se consideran sólo los aspectos
del comportamiento de A que también están incluidos en el comportamiento de B. (Es
posible que A introduzca nuevos comportamientos que B no tenga, pero esto sólo puede

modificar los comportamientos existentes de B en ciertas maneras; que veremos
enseguida).

2 Ejemplo: bicicletas

Suponga que tenemos una clase para representar bicicletas. He aquí una implementación
parcial de esa clase:


class Bicycle{

private int framesize;
private int chainringGears;
private int freewheelGears;
...


// devuelve el número de marchas de la bicicleta
public int gears() { return chainringGears *
freewheelGears; }
// devuelve el precio de la bicicleta
public float cost() { ... }
// devuelve el impuesto de venta que incide sobre la
bicicleta
public float salesTax() { return cost() * .0825; }
// ejecución: transporta al ciclista del trabajo a casa
public void goHome() { ... }
...
}


Una nueva clase que representa bicicletas con luces delanteras para poderse adaptar a la
falta de luz.


class LightedBicycle{

private int framesize;
private int chainringGears;
private int freewheelGears;
private BatteryType battery;
...
// devuelve el número de marchas de la bicicleta
public int gears() { return chainringGears *
freewheelGears; }
// devuelve el precio de la bicicleta
float cost() { ... }
// devuelve el impuesto de venta que incide sobre la
bicicleta
public float salesTax() { return cost() * .0825; }
// ejecución: transporta al ciclista del trabajo a
casa
public void goHome() { ... }
// ejecución: sustituye la pila existente por el
argumento b
public void changeBattery(BatteryType b);
...
}


Copiar todo el código resulta trabajoso y aumenta la posibilidad de incurrir en errores. (El
error puede provenir de un fallo en la copia o en la realización de una modificación
requerida). Además, si se encuentra un error en una versión, es fácil olvidarse de extender
el arreglo a todas las versiones del código. Por último, es muy difícil comprender la
distinción de las dos clases observando únicamente las diferencias en un cúmulo de
similitudes.

Java y otros lenguajes de programación utilizan el concepto de subclase para superar esas
dificultades. Este concepto permite reutilizar las implementaciones y sobrescribir los
métodos.

A continuación presentamos una implementación mejor de la clase LightedBicycle:


class LightedBicycle extends Bicycle{

class LightedBicycle{

...
// requiere: velocidad_del_viento < 20mph

private BatteryType battery;
...

// devuelve el precio de la bicicleta
float cost() { return super.cost() + battery.cost();
}
// ejecución: transporta al ciclista del trabajo a
casa
public void goHome() { ... }
// ejecución: sustituye la pila existente con el
argumento b
public void changeBattery(BatteryType b);
...
}


LightedBicycle no necesita implementar métodos y campos que aparecen en su
superclase Bicycle; las versiones de Bicycle son automáticamente utilizadas por Java
cuando no son sobrescritas en la subclase.

Considere la siguiente implementación del método goHome (junto con especificaciones
más completas). Si éstos son los únicos cambios, ¿son las clases LightedBicycle y
RacingBicycle subtipos de Bicycle? (De momento trataremos el concepto de
subtipos; más tarde volveremos a las diferencias entre las subclases Java, los subtipos Java,
y los verdaderos subtipos).

class Bicycle{

...
// requiere: velocidad_del_viento < 20mph && luz_del_dia
// ejecución: transporta al ciclista del trabajo a casa
public void goHome() { ... }
}


// ejecución: transporta al ciclista del trabajo a casa
void goHome() { ... }
}


class RacingBicycle{

...
// requiere: velocidad_del_viento < 20mph && luz_del_dia
// ejecución: transporta al ciclista del trabajo a casa
// en un período de tiempo < 10 minutos
// && hace al ciclista sudar
void goHome() { ... }
}


Para responder a esa pregunta, recuerde la definición de subtipificación: ¿puede un objeto
del subtipo ser sustituido en cualquier lugar donde el código espera un objeto del supertipo?
Si es así, la relación de subtipificación es válida.

En este caso, tanto LightedBicycle como RacingBicycle son subtipos de
Bicycle. En el primer caso, las condiciones son relajadas; en el segundo caso, la
ejecución se refuerza de una manera que aún satisface la ejecución de la superclase.

El método cost de LightedBicycle muestra otra capacidad de especialización de
clases en Java. Los métodos pueden ser sobrescritos para facilitar una nueva
implementación en una subclase. Esto permite una mayor reutilización del código; en
particular, LightedBicycle puede reutilizar el método salesTax de Bicycle.
Cuando se llama a salesTax en una LightedBicycle, la versión de Bicycle es la
que se utiliza. Entonces, la llamada de cost dentro de salesTax llama a la versión
basada en el tipo de tiempo de ejecución del objeto (LightedBicycle), con lo que se
utiliza la versión LightedBicycle. Independientemente del tipo declarado de un objeto,
la implementación de un método con muchas implementaciones (de la misma firma)
siempre se selecciona basándose en el tipo de tiempo de ejecución.

De hecho, un cliente externo no tiene manera de llamar a la versión de un método,
especificado por el tipo declarado o cualquier otro tipo, que no sea el tipo de tiempo de
ejecución. Ésta es una propiedad atractiva y muy importante de Java (y de otros lenguajes
orientados a objetos). Suponga que la subclase mantiene algunos campos adicionales que se
mantienen sincronizados con los campos de la superclase. Si los métodos de la superclase
pudieran llamarse directamente, posiblemente modificando campos de la superclase sin que
los campos de la subclase sean alterados también, entonces se violaría el invariante de
representación de la subclase.

De cualquier modo, una subclase puede llamar métodos de sus padres mediante la
utilización de super. A veces es útil cuando el método de la subclase necesita hacer un
poco más de trabajo; recuerde la implementación de LightedBicycle para cost:


class LightedBicycle extends Bicycle{

// devuelve el precio de la bicicleta

float cost() { return super.cost() + battery.cost();
}

}


Suponga que la clase Rider modela las personas que montan en bicicleta. En ausencia de
especializaciones de clase y de subtipos, el diagrama de dependencia modular tendría el
siguiente aspecto:



El código para Rider también tendría que probar que tipo de objeto se ha pasado, lo que
resultaría feo, ampuloso y propenso a errores.

Con la subtipificación, las dependencias de MDD se parecerían a esto:



Las diversas dependencias se han reducido a una.
Cuando se añaden las fechas de subtipo, el diagrama resulta apenas un poco más
complicado:






Aunque existan varias flechas, este diagrama es más sencillo que el original: las
restricciones de dependencia complican el diseño y la implementación más que otros tipos
de restricciones.

3 Ejemplo: cuadrado y rectángulo

Desde la escuela primaria sabemos que todo cuadrado es un rectángulo. Suponga que
queremos hacer del cuadrado Square un subtipo de Rectangle que incluya un método
setSize:


class Rectangle{
...

// ejecución: define la anchura width y la altura height
como los valores
// especificados (esto es, this.width’ = w &&
this.height’ = h)
void setSize(int w, int h);
}

class Square extends Rectangle{
...
}

¿Cuál de los siguientes métodos es adecuado para Square?


// requiere: w = h
void setSize(int w, int h);

void setSize(int edgeLenght);

// arroja la excepción BadSizeException si w != h
void setSize(int w, int h) throws BadSizeException;


El primero no resulta acertado porque el método de subclase exige más que el método de
superclase. Así, los objetos de subclase no se pueden sustituir por objetos de superclase, ya
que puede existir alguna parte del código que llame al método setSize con argumentos
diferentes.


El segundo no está en lo cierto (completamente), ya que la subclase aún debe especificar un
comportamiento para setSize(int, int); ésta es una definición de un método
diferente (cuyo nombre es el mismo pero cuya firma es d
  • Links de descarga
http://lwp-l.com/pdf6811

Comentarios de: Subtipos e Subclasses (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad