View
4
Download
0
Category
Preview:
Citation preview
A3F
Polimorfismo
Carlos Fontela
cfontela@fi.uba.ar
2c2010 2
A3F
Temario
Métodos virtuales
Métodos abstractos
Polimorfismo como concepto
Interfaces
Clases internas
2c2010 3
A3F
Analizar
cb := CuentaBancaria new.
cc := CuentaCorriente new.
cb extraer: 200.
cc extraer: 200.
Generación de lista de compras
2c2010 4
A3F
Analizar
CuentaBancaria cb = new CuentaBancaria(…);
CuentaCorriente cc1 = new CuentaCorriente(…);
CuentaBancaria cc2 = new CuentaCorriente(…);
cb.extraer(200);
cc1.extraer(200);
cc2.extraer(200);
Generación de lista de compras
2c2010 5
A3F
Métodos virtuales (1)
2c2010 6
A3F
Métodos virtuales (2)
“llama al dibujar de Elipse:”
unaElipse mover.
“llama al dibujar de Triangulo:”
unTriangulo mover.
“llama al dibujar de la clase de cada figura:”
coleccion dibujar.
En Java y en Smalltalk la “virtualidad” se da por defecto
En C# y C++ debemos declarar métodos como “virtual”
Métodos de clase, privados y finales no son virtuales
2c2010 7
A3F
Métodos virtuales (3)
Los métodos virtuales agregan ineficiencias
Pero garantizan reutilización
Eliminar la “virtualidad” sólo si se demuestra que no se van a
redefinir y la presunta ineficiencia
Un método debe ser virtual sí o sí cuando se lo redefinirá y
es llamado desde:
Un método en una clase ancestro
Un método que delegue en el método en cuestión de la clase
ancestro
En Smalltalk no hay opción: todo método de instancia es
virtual
2c2010 8
A3F
Ejemplo estándar en Java
En Object
public String toString ( ) { … }
System.out.println(…) usa toString()
Si quiero que un objeto sea imprimible, debo redefinir toString:
En CuentaBancaria
public String ToString() {
return titular;
}
Luego...
CuentaBancaria cuenta = new CuentaBancaria (12, ”Juan”);
System.out.println (cuenta);
2c2010 9
A3F
Métodos abstractos (1)
Nunca van a ser invocados: caso del dibujar de Figura
Las instancias de las subclases van a poder responder el mensaje
Pero sin definir comportamiento en la clase ancestro
A nivel de la clase madre sólo se puede prever la firma que tendrá
En lenguajes compilados, es también una necesidad de compilación
Corolarios
No tienen implementación
Deben redefinirse
Son virtuales
2c2010 10
A3F
Métodos abstractos: implementación
En Java y C#:
public void abstract dibujar();
Si una clase tiene métodos abstractos debe ser
abstracta
En Smalltalk
Convencional
Llamar a self subclassResponsibility
2c2010 11
A3F
Polimorfismo
Objetos de distintas clases de una misma familia entienden
los mismos mensajes
Igual semántica (significado)
Implementaciones diferentes
Un mismo mensaje puede provocar la invocación de métodos
distintos
Vinculación tardía
Se retarda la decisión sobre el método a llamar hasta el momento
en que vaya a ser utilizado
2c2010 12
A3F
Polimorfismo sin herencia (Smalltalk)
Los elementos deben ser “dibujables”
Lo que necesito es que esté presente el método dibujar en la clase
Si no => problemas en tiempo de ejecución
2c2010 13
A3F
Polimorfismo sin herencia (Java - 1)
El problema es que en Java hay compilación con
verificación de tipos
El compilador no va a permitir una llamada a dibujar()
desde un Object
¿Cómo lograr que las instancias de Figura y de
DiagramaUML sean “dibujables” para el compilador?
2c2010 14
A3F
Polimorfismo sin herencia (Java - 2)
Solución:
Hay una construcción llamada “interfaz”
2c2010 15
A3F
Interfaces: clases “muy abstractas” (1)
Son como clases
Abstractas
Con todos los métodos abstractos
Sin atributos (sin estado)
Ejemplo
public interface Imprimible {
/*public abstract*/ void imprimirDatos();
}
Pueden heredar de otras interfaces
public interface Dibujable extends Imprimible {
void dibujar();
}
2c2010 16
A3F
Interfaces: clases “muy abstractas” (2)
Uso
public class CajaAhorro extends CuentaBancariaimplements Imprimible {
...
}
Corolario
Si una clase declara implementar una interfaz y no implementa (redefine) uno de sus métodos es abstracta
2c2010 17
A3F
Interfaces: protocolos
Son grupos de métodos sin implementar
Una clase puede implementar varias
Ojo con los conflictos de nombres
2c2010 18
A3F
Interfaces y polimorfismo (1)
Variables cuyo tipo es una interfaz
Imprimible i = new Fecha(20,6,1964);
Imprimible[ ] lista = new Imprimible[3];
lista[0] = new Fecha (20, 1, 2000);
lista[1] = new Inmueble ( );
lista[2] = new Fecha (8, 6, 2002);
…
for (int i=0; i < 3; i++) lista[i].imprimirDatos();
Ojo que sólo puedo instanciar clases
2c2010 19
A3F
Interfaces y polimorfismo (2)
Cada objeto puede tener muchas “caras”
Fecha f = new Fecha(20,6,1964);
Imprimible i = f;
Comparable c = f;
Serializable s = f;
Todos se refieren al mismo objeto
Pero “lo ven” distinto
Cada variable sólo puede usar los métodos de su interfaz
2c2010 20
A3F
¿Qué es una interfaz?
Visión de lenguaje
Una clase “muy abstracta” que se puede usar para herencia múltiple
Visión desde el uso
Un tipo de datos que permite que ver a un mismo objeto con distintos tipos
=> Cada tipo implica un comportamiento
2c2010 21
A3F
Interfaces predefinidas
Caso de Comparable
En java.lang.Comparable
interface Comparable {
int compareTo (Object o);
}
Devuelve valores <0, 0 o >0
¡Muy útil en colecciones!
Hay otras predefinidas
Comparator, Serializable, Cloneable, etc.
2c2010 22
A3F
Uso de Comparable
public class Fraccion implements Comparable {
private int numerador;
private int denominador;
// otros métodos
public int compareTo(Object otro) {
Fraccion otra = (Fraccion) otro;
if (numerador * otra.denominador > denominador * otra.numerador)
return 1;
else if (numerador * otra.denominador < denominador * otra.numerador)
return -1;
else return 0;
}
}
2c2010 23
A3F
Comparable y arreglos
Clase Arrays: uso
Fraccion [ ] v = new Fraccion[4];
Arrays.sort (v);
int posicion = Arrays.binarySearch (v, x);
Método sort(): definición
public void sort (Comparable [ ] w) { … }
Si Fraccion implementa Comparable, puedo usar
Arrays.sort(v)
¿Y si no?
2c2010 24
A3F
Rarezas: Comparator
Si la clase de v no implementa Comparable, existe otro sort():
public void sort (Object [ ] v, Comparator c) { … }
Que puedo usar así:
Comparator comp = new ComparadorFracciones();
Arrays.sort (x, comp);
¿Y qué es ComparadorFracciones?
Una clase que implementa java.util.Comparator…
Y su método:
public int compare (Object o1, Object o2);
2c2010 25
A3F
Implementación del comparador
public class ComparadorFracciones implements java.util.Comparator {
public int compare (Object o1, Object o2) {
Fraccion f1 = (Fraccion)o1; Fraccion f2 = (Fraccion)o2;
if ( f1.getNumerador() * f2.getDenominador() >
f1.getDdenominador() * f2.getNumerador() )
return 1;
else if ( f1.getNumerador() * f2.getDenominador() <
f1.getDenominador() * f2.getNumerador() )
return -1;
else return 0;
}
}
2c2010 26
A3F
¿Qué hicimos?
Creamos una clase ¡que no tiene estado!
¡Y la instanciamos!
Tampoco se refiere a una entidad de dominio
Aparece por necesidades de diseño (solución)
Sólo sirve por el método que lleva dentro
Esto es un patrón de diseño: Command
Otro uso de Comparator:
Para definir otra forma de ordenamiento
2c2010 27
A3F
Claves
Métodos virtuales garantizan reutilización
genuina
Interfaces definen qué puede hacer un objeto
Polimorfismo = distintos comportamientos para
un mismo mensaje
2c2010 28
A3F
Lecturas obligatorias
Principios de diseño de Smalltalk, de Daniel H. H. Ingalls.
Lo tienen en:
http://www.smalltalking.net/Papers/stDesign/stDesign.htm
Domain Driven Design, de Eric Evans, capítulo 1
Lo tienen en: http://domaindrivendesign.org/sites/default/files/books/chapter01.pdf
2c2010 29
A3F
Lecturas opcionales
Orientación a objetos, diseño y programación, Carlos Fontela 2008, capítulos 7 y 8 “Polimorfismo basado en herencia” y “Polimorfismo basado en interfaces”
2c2010 30
A3F
Qué sigue
Excepciones
Colecciones e iteradores
Primer parcial
Recommended