Você está na página 1de 124

Programacin Orientada a Objetos

Tema 3: Propiedades Bsicas de la


Orientacin a Objetos

Eduardo Mosqueira Rey

LIDIA
Laboratorio de Investigacin y
desarrollo en Inteligencia Artificial

Departamento de Computacin
Universidade da Corua, Espaa
Objetivos
Conocer y analizar las principales propiedades
de la orientacin a objetos
Estas propiedades incluirn aquellas que son
compartidas por los tipos abstractos de datos
(como abstraccin, encapsulacin,
modularidad), como aquellas propias de la
orientacin a objetos (herencia, polimorfismo,
ligadura dinmica, etc.).
Estudiar cmo un lenguaje como Java
implementa, en mayor o menor medida, dichas
propiedades bsicas.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 2
ndice
1. Abstraccin
2. Encapsulamiento
3. Modularidad
4. Jerarqua
5. Polimorfismo
6. Tipificacin
7. Ligadura dinmica

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 3


ndice
1. Abstraccin
Definicin y caractersticas

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 4


Abstraccin
Definicin y caractersticas
Definicin
Representacin de las caractersticas fundamentales de algo
sin incluir antecedentes o detalles irrelevantes
Caractersticas
Es uno de los mtodos fundamentales para enfrentarse a la
complejidad inherente al software (ya visto en los TADs).
La OO fomenta que el uso de abstracciones en los datos y
procedimientos para simplificar la descripcin del problema
El elemento clave de la abstraccin es la clase
Clase Descripcin abstracta de un grupo de objetos, cada uno de
los cuales se diferencia por su estado especfico y por la
posibilidad de realizar una serie de operaciones.
Ejemplo, Esfera
Estado: coordenadas del centro y radio
Operaciones: mover el centro, cambiar el radio.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 5


ndice
2. Encapsulamiento
Definicin y caractersticas
Ventajas

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 6


Encapsulamiento
Definicin y caractersticas
Definicin
Proceso de almacenar en un mismo compartimiento los elementos de
una abstraccin que constituyen su estructura y su comportamiento
Caractersticas
Abstraccin y el encapsulamiento son conceptos complementarios:
La abstraccin se centra en el comportamiento observable de un objeto
El encapsulamiento se centra en la implementacin que da lugar a ese
comportamiento.
El encapsulamiento tambin implica ocultacin de informacin
Cada objeto revela lo menos posible de su estructura interna
parte pblica interfaz, parte privada implementacin.
Ejemplos
Una operacin es vista por sus usuarios como si fuera una simple entidad,
aunque est formada por una secuencia de operaciones a bajo nivel.
Un objeto es visto como un simple objeto en vez de como una composicin
de sus partes individuales.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 7
Encapsulamiento
Ventajas
Ventajas
La supresin de los detalles de bajo nivel nos
permite razonar acerca de la operacin u objeto de
forma ms eficiente.
Un cambio en la representacin de una abstraccin
puede no obligar a un cambio en los clientes que la
utilicen
Cambios en el diseo que no afecten al interfaz no se
propagan
Podemos cambiar una funcin por otra ms eficiente sin
afectar a los usuarios de dicha funcin
Muy importante ya que facilita el mantenimiento del software
Java
La encapsulacin se consigue a travs del concepto de
clase combinado con los especificadores de acceso que
limitan la visibilidad de los atributos y mtodos.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 8
ndice
3. Modularidad
Definicin y caractersticas
Modularidad en Java

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 9


Modularidad
Definicin y caractersticas
Definicin
Propiedad que tiene un sistema que ha sido descompuesto en
un conjunto de partes o mdulos que sean cohesivos y
dbilmente acoplados
Cohesivos agrupan abstracciones que guardan relacin lgica
Dbilmente acoplados minimizan las dependencias entre mdulos

Ventajas
El hecho de fragmentar un programa en componentes
individuales suele contribuir a reducir su complejidad
Permite crear una serie de fronteras bien definidas y dentro del
programa aumenta la comprensin del mismo.
Sinergia entre abstraccin, encapsulamiento y
modularidad
Un objeto proporciona una frontera bien definida alrededor de
una sola abstraccin, el encapsulamiento y la modularidad
proporcionan barreras que rodean a esa abstraccin.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 10
Modularidad
Definicin y caractersticas
Abstraccin, Encapsulamiento y Modularidad
mensaje

Mdulo
Parte pblica
Objeto 1
Objeto 2

Estado
Estado
Interfaz
Interfaz

Parte privada
Objeto 3
Objeto 4
Objeto 5
Estado
Estado
Interfaz Estado
Interfaz
Interfaz

11
Modularidad
Modularidad en Java
Clases
Encapsulan los atributos y mtodos de un tipo de
objetos en un solo compartimiento
Ocultan, mediante los especificadores de acceso, los
elementos internos que no se pretende publicar al
exterior.
Esta proteccin es altamente configurable al existir
varios niveles de acceso:
public
protected
por defecto (package)
private
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 12
Modularidad
Modularidad en Java
Ficheros
Unidades fsicas de compilacin
Dentro de un fichero .java pueden residir varias
clases con las siguientes restricciones
Slo puede haber una clase pblica por fichero
El nombre del fichero debe ser el mismo que el de la clase
pblica
Si no existe ninguna clase pblica tampoco existe ninguna
restriccin con respecto al nombre del fichero
Compilacin
La compilacin de un fichero .java genera tantos ficheros
.class (bytecodes) como clases existen en dicho fichero
Para facilitar la compilacin Java recompila los ficheros
.java si tienen el mismo nombre que un fichero .class
pero con una fecha posterior.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 13


Modularidad
Modularidad en Java
Paquetes
Unidades lgicas de agrupacin de clases
Las clases pueden ser
Pblicas: forman parte del interfaz de su paquete
No pblicas: slo son visibles a clases de su mismo paquete
Definicin
Se utiliza la directiva package al principio de cada fichero.
En caso de que no se especifique paquete se considera que todas las
clases que se encuentran en el paquete por defecto
Jerarquas de paquetes
El nombre del paquete puede tener varios niveles, lo que facilita su
organizacin (java.util, java.util.jar, java.awt, java.awt.color, etc.).
De todas formas no existe el concepto de subpaquete ni relaciones
jerrquicas entre paquetes (la relacin entre java.util y java.util.jar es la
misma que entre java.util y javax.swing son dos paquetes distintos).
Simplemente se permite una organizacin jerrquica de los nombres
de los paquetes por motivos de organizacin y claridad

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 14


Modularidad
Modularidad en Java
Objetivos de los paquetes:
Disear un dispositivo de modularidad de nivel superior a las
clases.
Cada paquete puede tener sus propias clases privadas
desconocidas para aquella persona que quiera utilizar el paquete.
Agrupar clases con funcionalidades similares.
De forma que sean ms fciles de localizar y pueda verse
claramente que las clases estn relacionadas.
Organizar fsicamente los ficheros fuente.
Para poder utilizar las clases compiladas, los ficheros .class deben
estar disponibles en el directorio indicado por la variable de
entorno CLASSPATH.
Para organizar el directorio del CLASSPATH Java equipara los
nombres de paquetes con los directorios en disco (Java buscar
las clases del paquete com.miempresa.utils en el directorio
CLASSPATH/com/miempresa/utils).

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 15


Modularidad
Modularidad en Java
Objetivos de los paquetes (cont.):
Prevenir conflictos de nombre y favorecer la
reutilizacin.
Los nombre de las clases pueden entrar en conflicto, para
evitarlo la clase se compone de el nombre del paquete al que
pertenece, un punto y el nombre de la clase
Pueden existir conflictos con los nombres de los paquetes
Para evitar esto existe el convenio de utilizar como prefijo a
los nombres de los paquetes los nombres invertidos del
dominio de Internet de la empresa que los ha desarrollado
Ejemplo, los paquetes de Borland tendran el prefijo
com.borland, los paquetes del OMG tendra el prefijo
org.omg, etc.
Los nombres de dominio no pueden repetirse, evitando as
los posibles conflictos
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 16
Modularidad
Modularidad en Java
La sentencia import
Para simplificar la sintaxis y no tener que introducir un nombre
largo de paquete cada vez que se utiliza una clase puede
utilizarse la sentencia import al principio de cada fichero
De esta forma puede utilizarse el nombre de la clase sin indicar
el paquete al que pertenece
La sentencia import puede utilizarse de dos formas distintas:
import nombrepaquete.* importa todas las clases del paquete
import nombrepaquete.Clase importa slo la clase especificada
La sentencia import simplemente especifica que los contenidos
pblicos del paquete destino entran en el espacio de nombres
del origen. No es necesario incluir la sentencia import para dar
privilegios de acceso de un paquete a otro
Si dos clase de distintos paquetes comparten nombre se deber
usar su path completo.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 17


Modularidad
Modularidad en Java
Ejemplo
Por conveccin los nombres de los paquetes de java se escriben
siempre en minsculas (incluidas las primeras letras de cada palabra)
Utilizacin

...

paqueteuno.MiClase x = new
Definicin
paqueteuno.MiClase();
fichero MiClase.java
...

package paqueteuno;

public class MiClase


{ import paqueteuno.*;
... ...
}
MiClase x = new MiClase();
...

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 18


ndice
4. Jerarqua
Herencia
Herencia simple vs. mltiple
Clases abstractas
Interfaces
Composicin

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 19


Jerarqua
Definicin de jerarqua
Una jerarqua es una clasificacin de las
abstracciones

Jerarqua de generalizacin/especializacin:
Define relaciones ES_UN
Tambin se conoce como herencia

Jerarqua de agregacin:
Define relaciones ES_PARTE_DE
Tambin se conoce como composicin

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 20


Jerarqua
Herencia
Herencia
Define una relacin entre clases, en las que una
clase comparte la estructura de comportamiento
definida en una o ms clases
La herencia permite declarar las abstracciones con
economa de expresin

Subclases y superclases
Una subclases hereda de una o ms superclases y
aumenta o redefine la estructura y el comportamiento
de dichas superclases
Las subclases representan conceptos especializados
Las superclases representan generalizaciones de los
aspectos comunes de las subclases
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 21
Jerarqua
Herencia
Representacin interna de los objetos

Por ejemplo, Informacin de


un puntero a la la clase
superclase
Variables de Tabla de
clase punteros a
mtodos
Puntero a la ...
constructores
clase
...
Variables de Tabla de
instancia punteros a
Puntero del mtodos de
objeto ... clase

...
Tabla de
... punteros a
mtodos de
instancia

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 22


Jerarqua
Herencia
Representacin interna de los objetos
class Persona public static int getMayoriaEdad()
{ { return mayoriaEdad;}
protected String nombre;
protected String apellidos; public static void setMayoriaEdad
protected int edad; (int me)
protected int genero; { if (me > 0) mayoriaEdad = me; }
protected static
int mayoriaEdad = 18; public String getNombre()
public static final int HOMBRE = 1; { return nombre;}
public static final int MUJER = 2;
public static final public void setNombre(String n)
int DESCONOCIDO = 99; { nombre = n; }

public Persona() public String getApellidos()


{ { return apellidos;}
nombre = "";
apellidos = ""; public void setApellidos(String a)
edad = 0; { apellidos = a; }
genero = DESCONOCIDO;
} public int getEdad()
{ return edad;}
public Persona(String n, String a,
int e, int g) public void setEdad(int e)
{ { if (e > 0) edad = e; }
nombre = n;
apellidos = a; public int getGenero()
edad = e; { return genero;}
genero = g ;
} public void setGenero(int g)
{ if (g==1 || g==2 || g==99)
genero = g;}
}
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 23
Jerarqua
Herencia
Representacin interna de los objetos
Puntero a
la clase Persona()

nombre = Juan Persona


Puntero del (String, String, int, int)
apellidos = Garca Informacin de la clase
objeto
Persona
edad = 15 getMayoriaEdad()
mayoriaEdad = 18
genero = HOMBRE setMayoriaEdad(int)
HOMBRE = 1
getNombre()
MUJER = 2
setNombre(String)
Puntero a DESCONOCIDO = 99
la clase getApellidos()

nombre = Ana setApellidos(String)


Puntero del
objeto apellidos = Prez getEdad()

edad = 21 setEdad(int)

genero = MUJER getGenero()

setGenero(int)

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 24


Jerarqua
Herencia
Representacin interna de los objetos con herencia
class Estudiante extends Persona
{
public final static int II = 1;
public final static int ITIG = 2;
public final static int ITIS = 3;
private int titulacion;
public String [] asignaturas;

public int getTitulacion()


{ return titulacion;}

public void setTitulacion(int t)


{ if (t == 1 || t==2 || t==3)
titulacion = t; }

public float calcularMatricula()


{ ... }
}

class Profesor extends Persona


{
public String departamento;
public String categoria;
public String dedicacion;
public java.util.Date antiguedad;

public float calcularSueldo()


{ ... }
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 25


Jerarqua
Herencia
Representacin interna de los objetos con herencia
elementos heredados Estudiante()

elementos propios
getMayoriaEdad()
Informacin de la clase
setMayoriaEdad(int)
Estudiante

Puntero a mayoriaEdad = 18 getNombre()


la clase
HOMBRE = 1 setNombre(String)
nombre
MUJER = 2 getApellidos()
apellidos
Puntero del DESCONOCIDO = 99 setApellidos(String)
objeto edad
II = 1 getEdad()
genero
ITIG = 2 setEdad(int)
titulacion
ITIS = 3 getGenero()
asignaturas
setGenero(int)

getTitulacion()

setTitulacion(int)

calcularMatricula()

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 26


Jerarqua
Herencia
Representacin interna de los objetos con herencia

elementos heredados Profesor()

elementos propios
getMayoriaEdad()
Puntero a
la clase
setMayoriaEdad(int)
Informacin de la clase
nombre Profesor
getNombre()
apellidos mayoriaEdad = 18
setNombre(String)
edad HOMBRE = 1
Puntero del getApellidos()
objeto genero MUJER = 2
setApellidos(String)
departamento DESCONOCIDO = 99
getEdad()
categoria
setEdad(int)
dedicacin
getGenero()
antiguedad
setGenero(int)

calcularSueldo()

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 27


Jerarqua
Herencia
Aspectos importantes a recordar
Un objeto de una subclase siempre incluye en su interior un
objeto de la superclase

Estudiante

Persona

Object

Los elementos definidos en una superclase aparecen siempre


en la misma posicin en las subsecuentes subclases

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 28


Jerarqua
Herencia
Qu constructor habr que poner en SubClase?
Todo objeto de una subclase es un objeto de una superclase
La palabra clave para llamar a un constructor de la superclase
es super (la palabra clave this se utilizaba para llamar a un
constructor de la propia clase)
class SuperClase
{
int valor;
public SuperClase(int valor)
{ this.valor = valor; }
}

class SubClase extends SuperClase


{

}
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 29
Jerarqua
Herencia
Herencia y constructores
Los constructores no se heredan, son exclusivos de la clase en
la que se definen
Por ello la primera instruccin de un constructor de una
subclase es llamar al constructor de la superclase, y este a su
vez al de su superclase hasta llegar a la clase Object
Esta llamada generalmente est implcita y consiste en una
llamada al constructor sin parmetros. Si queremos hacerla
explcita deberemos poner super() como primera instruccin
Si el constructor sin parmetros no existe la llamada implcita
fallar y ser necesario hacer una llamada explcita:
super(param1, param2)

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 30


Jerarqua
Herencia
Estructura de las jerarquas de herencia

Clase raz

Clases interiores

Clases hoja

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 31


Jerarqua
Herencia simple vs. mltiple
Herencia simple
Cada clase tiene, como mximo, un ancestro
Ejemplos: Java, Object Pascal y C#
Herencia mltiple
Una clase puede heredar de varias clases simultneamente
Ejemplos: C++ y Eiffel
Tendencia actual:
Eliminacin de la herencia mltiple a favor de la herencia simple.
Motivo: los conflictos que genera y su resolucin
Que pasa cuando heredamos el mismo elemento de dos clases distintas?
Los mecanismos para resolver estos conflictos son especficos de cada
lenguaje y aumentan la complejidad de la programacin y reducen la
comprensibilidad
Existen mecanismos como los interfaces que permiten simular una cierta
herencia mltiple que evita los conflictos y permiten diseos elegantes de
clases.
Es posible desarrollar jerarquas de herencia complejas y flexibles evitando
la herencia mltiple

32
Jerarqua
Clases abstractas
Caractersticas
Representan conceptos generales que agrupan
mtodos comunes y dejan para la implementacin de
las subclases mtodos especficos.
No pueden ser instanciadas
Un mtodo abstracto slo puede pertenecer a una
clase abstracta, pero una clase abstracta puede tener
mtodos no abstractos
Las subclases de una clase abstracta deben
implementar los mtodos abstractos o declararse
como abstractas.

33
Jerarqua
Clases abstractas

Circulo Rectangulo

X: int
X: int Y: int
Y: int Estado
largo: int
radio: int ancho: int

calcularPerimetro(): float calcularPerimetro(): float


calcularArea(): float Comportamiento calcularArea(): float
void moverA() moverA(x:int, y:int) moverA(x:int, y:int)
{ void moverA()
this.X=X; {
this.Y=Y; this.X=X;
} float calculaArea() float calculaArea() this.Y=Y;
{ return Math.PI * radio * radio; } { return largo * ancho; } }

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 34


Jerarqua
Clases abstractas

Figura

X: int
Y: int

calcularPerimetro(): float
calcularArea(): float

Circulo Rectangulo

X: int
X: int Y: int
Y: int largo: int
radio: int ancho: int

calcularPerimetro(): float calcularPerimetro(): float void moverA()


calcularArea(): float calcularArea(): float {
void moverA() moverA(x:int, y:int) moverA(x:int, y:int)
this.X=X;
{
this.Y=Y;
this.X=X;
}
this.Y=Y;
} float calculaArea() float calculaArea()
{ return Math.PI * radio * radio; } { return largo * ancho; }

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 35


Jerarqua
Clases abstractas
class Circulo extends Figura
{
private int radio;
// Nota: Se omiten constructores y mtodos
m todos de
// lectura y escritura de atributos
public float calcularPerimetro()
{ return 2*(float)Math.PI*radio; }
abstract class Figura
{
public float calcularArea()
private int X;
{ return (float)Math.PI*radio*radio;
float }
private int Y;
}
public abstract float calcularPerimetro();
class Rectangulo extends Figura
public abstract float calcularArea();
{
private int largo;
public void moverA (int X, int Y)
private int ancho;
{
this.X=X;
public float calcularPerimetro()
this.Y=Y;
{ return (largo*2)+(ancho*2); }
}
}
public float calcularArea()
{ return largo*ancho; }
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 36


Jerarqua
Interfaces
Definicin
Son clases abstractas puras ya que slo definen un protocolo
de conducta y no como debe implementarse dicha conducta.
[public] interface NombreInterfaz [extends SuperInterfaz, ...]
{ /* cuerpo del interfaz */ }

Caractersticas
Se definen con la palabra clase interface y no class
Contienen las cabeceras de mtodos que son, implcitamente,
pblicos y abstractos, pero no incluyen los cuerpos de los
mtodos
Pueden contener atributos pero sern implcitamente static y
final, es decir, constantes de clase
Ejemplo:
interface FiguraInterfaz
{
float calcularPerimetro();
float calcularArea();
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 37


Jerarqua
Interfaces
Herencia EN los interfaces
Siguen una jerarqua de herencias paralela a la jerarqua de
herencias de las clases.
Permite la herencia mltiple entre interfaces
Herencia DE interfaces (implementacin)
Cualquier clase puede heredar (definido a travs de la palabra
clave implements) de varios interfaces
No se dan los problemas que veamos con la herencia mltiple
y las clases ya que no se hereda la implementacin de los
mtodos sino las cabeceras, por lo que los posibles conflictos
son ms sencillos de solucionar.
Si una clase implementa un interfaz debe dar implementacin a
todos los mtodos incluidos en su interfaz (incluidos los
superinterfaces que extiende) o bien declararse abstracta y
diferir la implementacin del interfaz a sus subclases
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 38
Jerarqua
Interfaces
Representacin de las jerarquas de clases e interfaces

class X interface A interface B

class Y interface C interface D

class W class Z interface E

Hereda los mtodos de las clases X e Y.


Debe implementar los mtodos de los
interfaces A, B, C y D

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 39


Jerarqua
Interfaces
Ejemplo: clase que encapsula el
funcionamiento de un vector de datos
public class Vector
{
private int[] datos;

public Vector(int valores)


{
datos = new int[valores];
for (int i = 0; i < datos.length; i++)
{ datos[i] = 0; }
} La clase Vector tiene un mtodo que devuelve
un iterador sobre la misma.
public int getValor(int pos)
{ return datos[pos]; } En principio hemos implementado ese
iterador como una clase aparte a la cual se le
public void setValor(int pos, int valor) pasan los datos internos del vector
{ datos[pos] = valor; }

public int dimension()


{ return datos.length; }

public Iterator iterador()


{
return new IteradorVector(datos);
}
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 40


Jerarqua
Interfaces
remove es una operacin

Definicin del
public interface Iterator
{ opcional. Eso en la semntica de
boolean hasNext(); las bibliotecas de colecciones de Java
Object next(); significa que la clase implementadora

interfaz Iterator }
void remove(); no est obligada a darle una
implementacin.

Definicin de un iterador para el vector


class IteradorVector implements Iterator
{ Implementamos el interfaz Iterator de java.util
int[] datos;
int cursor = 0;
A la clase IteradorVector le pasamos el
public IteradorVector(int[] array) estado interno del vector para que lo recorra.
{ datos = array; } Aqu el riesgo est en que el vector cambie
public boolean hasNext()
durante la iteracin. Los iteradores del API
{ de Java son fail-fast, es decir, lanzan una
if (cursor < datos.length) return true; excepcin si se modifican los datos durante
else return false; la iteracin
}

public Object next() Como el lenguaje Java obliga a darle una


{
int valor = datos[cursor];
implementacin a todos los elementos de un
cursor++; interfaz al implementarlo hay que darle una
return valor; implementacin a remove, pero ser para
} lanzar una excepcin indicando que la
operacin no est soportada
public void remove()
{ throw new UnsupportedOperationException("Not supported"); }
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 41


Jerarqua
Interfaces
Ejemplo de utilizacin del iterador
Definimos i como una variable de tipo
Iterator. Aunque no podemos instanciar
interfaces o clases abstractas s podemos
declarar variables de esos tipos

El mtodo iterador de la clase Vector devuelve


public static void main(String[] args) un iterador sobre el mismo. Como vemos es
{ posible hacer una construccin del tipo
Vector v = new Vector(4);
v.setValor(0, 10);
Interface f = new ClaseImplementadora();
v.setValor(1, 11);
v.setValor(2, 12);
v.setValor(3, 13); El bucle itera hasta que hasNext es falso. La
parte de incrementacin del for se deja vaca
for(Iterator i = v.iterador(); i.hasNext(); ) porque de eso se encarga el propio mtodo
System.out.println(i.next());
next
}

next devuelve el objeto actual y mueve el


cursor hasta el siguiente objeto

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 42


Jerarqua
Interfaces
Ejemplo de ocultacin de la implementacin

... ImprimeIteracin acepta como parmetro una


clase que implementa Iterator pero
Vector.imprimeIteracion(v.iterador()); DESCONOCE CUL ES, y se encarga de
recorrerla tal y como establece el iterador
...

Este cdigo funcionar con cualquier clase que


public static void imprimeIteracion(Iterator i) implemente Iterator, incluso con clases que
{ sean creadas DESPUS de esta (el nuevo
for( ; i.hasNext(); )
cdigo no obliga a modificar el preexistente y se
System.out.println(i.next());
}
integra con l)

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 43


Jerarqua
Interfaces
Usos tpicos de los interfaces:
1. Capturar las similitudes entre clases no
relacionadas
2. Revelar el interfaz de programacin de un
objeto sin revelar su clase
3. Definir nuevos tipos de datos
Usos poco recomendados:
4. Marcadores de clase
5. Contenedores de elementos globales
6. Simular un tipo de herencia mltiple
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 44
Jerarqua
Interfaces
1. Capturar las similitudes entre clases no
relacionadas sin forzar una relacin de clases
artificiosa.
Una clase puede implementar los interfaces que quiera
(La clase IteradorVector puede actuar como verse como
un iterador, pero tambin puede implementar otros
interfaces como Serializable, Cloneable, etc.)
Si utilizamos instanceof descubriremos que una
instancia de IteratorVector es tambin una instancia
de Iterator (o de Serializable o Cloneable si fuera el
caso)
Sin embargo, si una clase hereda de una clase abstracta
no puede heredar de ninguna otra clase
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 45
Jerarqua
Interfaces
2. Revelar el interfaz de programacin de un objeto sin
revelar su clase.
Los interfaces se utilizan a menudo como intermediarios para
desacoplar las clases usuarias de funciones de las clases que
implementan dichas funciones.
Por ejemplo: una clase Cliente utiliza la clase Servicio a
travs del interfaz Indireccion. La clase Cliente no conoce
realmente que clase implementa Indireccion por lo que se
pueden realizar cambios en la clase Servicio sin que el cliente
se vea alterado.
En nuestro ejemplo el mtodo imprimeIteracin sera el
cliente, el interfaz sera Iterator y la clase que ofrece el
servicio sera IteradorVector
Utiliza >
1 1 <<interface>>
Cliente Servicio
Indireccion

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 46


Jerarqua
Interfaces
3. Definir nuevos tipos de datos
Mltiples objetos de clases diferentes pueden ser tratados
como si fueran de un mismo tipo comn, donde este tipo
viene indicado por el interfaz
No se pueden instanciar objetos en s del tipo interfaz ya que
la definicin de un interfaz no tiene constructor, por lo que no
es posible invocar el operador new sobre un tipo interfaz
Sin embargo si pueden declararse atributos del tipo del
interfaz y asignarle a estos atributos objetos de una clase que
implemente dicho interfaz
En el ejemplo al crear el interfaz Iterator estamos creando
un nuevo tipo de datos cuya implementacin viene dada por
cualquier objeto de una clase que implemente dicho interfaz

Interface f = new ClaseImplementadoraInterfaz();

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 47


Jerarqua
Interfaces
4. Marcadores de clase
Pueden utilizarse interfaces vacios como un flag,
un marcador para sealar a una clase con una
propiedad determinada.
Por ejemplo Java incluye en su API el interfaz
Cloneable que sirve para indicar que dicho objeto
se puede clonar, o Serializable para marcar un
objeto como almacenable en disco.
Actualmente suele ser ms recomendable usar las
annotations del Java SE 5
class MiClase implements Cloneable
{ ... }

MiClase x = new MiClase();


if (x instanceof Cloneable)
{...}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 48


Jerarqua
Interfaces
Anotaciones (Anexo)
Las anotaciones son metadatos, es decir, informacin sobre los
elementos del programa
Vienen a ser algo similar a las etiquetas del javadoc (@author)
pero aplicadas al cdigo, no a los comentarios
Por defecto Java incluye tres anotaciones
Override: anota a un mtodo e indica que sobreescribe a otro de la
superclase
Deprecated: indica que un mtodo o clase est anticuado y no debe
usarse (depreciado en la jerga de Java)
SupressWarnings: el compilador no avisa de warnings ocurridos
sobre el elemento anotado
Las anotaciones no son mas que interfaces por lo que pueden
declarar mtodos o constantes
La potencia de las anotaciones viene de la posibilidad de crear
anotaciones personalizadas
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 49
Jerarqua
Interfaces
Ejemplos de anotaciones
Cul es el resultado de la compilacin y ejecucin del
siguiente cdigo? class MiClase
{
@Override
public boolean equals(MiClase o)
{ return false; }
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 50


Jerarqua
Interfaces
Ejemplos de anotaciones

@SuppressWarnings(value={"unchecked"}) Indica que el compilador obvie los warnings


class MiClase generados en esta clase. Por ejemplo, usar un
{ ArrayList sin usar genericidad
List l = new ArrayList();

public void hola() Declaramos el mtodo como depreciado para que


{ l.add("Hola"); } lo sepa el compilador.
@Deprecated public void hazAlgo() No confundir con la etiqueta del javadoc, aunque
{} el compilador tambin la reconoce (pero por
} motivos de compatibilidad hacia atrs )

Debe usarse las dos etiquetas al mismo tiempo

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 51


Jerarqua
Interfaces
Mas ejemplos en Java 1.5 Tiger: A
Anotaciones personalizadas developers notebook

Import java.lang.annotation.*;
Anotamos la anotacin indicando que
@Retention(RetentionPolicy.RUNTIME) queremos que su informacin se
@interface EnDesarrollo mantenga en tiempo de ejecucin (
{ int porcentaje(); } para utilizarla con la reflexin)

@EnDesarrollo (porcentaje=50)
class MiClase { } La palabra clave para definir
anotaciones es @interface, el resto de
public class AnotacionSimple la declaracin es como si fuera un
{ interface tpico. En este caso
public static void main(String[] args) indicamos que existe un mtodo que
{ devuelve un porcentaje
MiClase x = new MiClase();
Class c = x.getClass(); Anotamos una clase con la anotacin
if (c.isAnnotationPresent(EnDesarrollo.class)) EnDesarrollo, le damos un valor a
{ porcentaje (el compilador nos evita
System.out.println("Esta clase est en desarrollo"); tener que escribir la sobreescritura del
EnDesarrollo ed = (EnDesarrollo)c.getAnnotation(EnDesarrollo.class); mtodo porcentaje por MiClase)
System.out.println("Porcentaje = " + ed.porcentaje());
} Usamos la reflexin para obtener
} informacin en tiempo de ejecucin del
}
objeto de tipo MiClase
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 52
Jerarqua
Interfaces
5. Como contenedores de elementos globales al
programa
En Java no existen variables globales como en
otros lenguajes. Los interfaces pueden utilizarse
para incluir aspectos comunes que deban
compartir clases heterogneas, como por ejemplo:
constantes

public interface Constantes public class Circulo implements Constantes


{ { int radio ;
public double PI = 3.1416; public double perimetro()
public int MAXFILAS = 15; { return (2 * PI * radio); }
} }

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 53


Jerarqua
Interfaces
Como contenedores de elementos globales al programa
Mala solucin: polucin del API exportado
Confusin entre los clientes
Compromiso a largo plazo
Soluciones
Definir las constantes en una clase o interfaz relacionado: Como
MIN_VALUE y MAX_VALUE en Integer
Crear clases que sean tipos enumerados
Definir las constantes en clases de utilidad (utility classes) como
por ejemplo Math
public class Constantes
{
private Constantes () {} // Para prevenir instanciacin
public static final double PI = 3.1416;
public static final int MAXFILAS = 15;
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 54


Jerarqua
Interfaces
Como contenedores de elementos globales al programa
Nuevo problema:
Hay que anteceder el nombre de la clase al nombre de la constante
perimetro = 2 * Constantes.PI * radio;

Soluciones al nuevo problema


Utilizar constantes locales: mala y confusa solucin
private static final double PI = Constantes.PI;

Utilizar la facilidad de importacin esttica (versin 1.5)


import static es.udc.Constantes.*; Los import static importan un elemento de una clase o todos
los elementos de una clase. Los import tradicionales
public class Circulo importaban una clase o todas las clases de un paquete
{
... No es necesario indicar a qu clase pertenece PI
int radio ;
public double perimetro() Qu problema plantean?
{ return (2 * PI * radio); }
...
}
55
Jerarqua
Interfaces
6. Para simular un tipo de herencia mltiple
Hay autores que destacan que los interfaces son la forma que
tiene Java de implementar la herencia mltiple.
Sin embargo esto no es del todo cierto ya que la herencia
mltiple como se conoce por ejemplo en C++ y los interfaces
presentan una serie de importantes diferencias:
No se pueden heredar variables desde un interface.
No se pueden heredar implementaciones de mtodos desde un
interface.
La herencia de un interface es independiente de la herencia de la
clase, las clases que implementan el mismo interface pueden o no
estar relacionadas a travs del rbol de clases.
Lo que s es cierto es que los interfaces parecen una
alternativa para resolver algunos problemas que en otros
lenguajes se resuelven utilizando herencia mltiple.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 56


Jerarqua
Interfaces
Interfaces o clases <<interface>>
Collection

abstractas?
API de colecciones <<interface>>
Set AbstractCollection
<<interface>>
List

Interfaces en un primer
nivel <<interface>>
SortedSet AbstractSet AbstractList

Clases abstractas en un
segundo nivel TreeSet HashSet ArrayList AbstractSequentialList

Tienes la opcin de
implementar el interfaz <<interface>>

directamente o heredar Map LinkedList

de una clase abstracta


<<interface>>
SortedMap AbstractMap

TreeMap HashMap WeakHashMap

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 57


Jerarqua
Interfaces
Qu problemas plantea el tener que pasar el
estado completo de un Vector a su iterador?
public class Vector
{
int[] datos:

...

public Iterator iterador()


{
return new IteradorVector(datos);
}

...
}

class IteradorVector implements Iterator


{
...

public IteradorVector(int[] array)


{ datos = array; }

...
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 58


Jerarqua
Interfaces
Clases internas
Una solucin para que una clase use datos privados
de otra es usar clases internas
Una clase interna es una clase definida dentro de
otra clase
La clase interna, al estar dentro de una clase
contenedora, tiene acceso a los elementos privados
de dicha clase contenedora
La utilidad de las clases internas se ve en ejemplos
como la definicin de clases iteradoras o las clases
de gestin de eventos de una JFrame Swing
El inconveniente que tienen es que a veces su
sintaxis llega a ser realmente confusa, la propuesta
de aadir Clousures al lenguaje se hace para
facilitar la sintaxis de las clases internas annimas
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 59
Jerarqua
Interfaces
Iterador definido con clases internas
public class Vector
{
private int[] datos;
public Vector(int valores)
{ datos = new int[valores];
for (int i = 0; i < datos.length; i++)
{ datos[i] = 0; }
}

public int getValor(int pos) { return datos[pos]; }


public void setValor(int pos, int valor) { datos[pos] = valor; } Ahora ya no es necesario pasarle la
public int dimension() { return datos.length; } informacin privada del Vector al iterador
public Iterator iterador() { return new Iterador(); }

class Iterador implements Iterator


La clase Iterador est definida por completo
{
int cursor = 0; dentro del mbito de la clase Vector

public boolean hasNext()


{ if (cursor < datos.length) return true; La clase Iterador implementa el interfaz
else return false; Iterator, pero la clase Vector no. Esa
}
posibilidad da mucho juego al uso de clases
public Object next() internas
{ int valor = datos[cursor];
cursor++;
return valor; Al pertenecer a la clase Vector puede ver sus
}
elementos privados sin ningn tipo de
public void remove() problema
{ throw new UnsupportedOperationException("Not supported yet."); }
}
}
60
Jerarqua
Interfaces
Aunque el trmino clase interna se ha generalizado, segn Java
una clase dentro de otra clase se considera una clase anidada
nested classes
Existen dos tipos de clases anidadas estaticas y no estticas
Clases internas no estticas (inner classes).
Como las vistas hasta ahora
Las instancias de las clases internas estn asociadas a una instancia
de la clase exterior, de la cual pueden ver sus elementos privados
Clases anidadas estticas (static nested classes).
Se definen anteponiendo static al nombre de la clase
Los objetos de la clase interna no tienen acceso a un objeto de la clase
externa
Para crear objetos de la clase interna hay que anteponer el nombre de
la clase externa (igual que se hace para otros elementos estticos).
Ambos tipos pueden ser definidos como clases privadas, eso
significa que son clases destinadas para ser usadas slo dentro de
la clase circundante.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 61


Jerarqua
Composicin
Caractersticas
La composicin define relaciones ES_PARTE_DE y ocurre
cuando los atributos de un objeto son a su vez objetos.
class Baraja class Carta
{ {
private Carta [] cartas; private int numero;
private String palo;
public Baraja()
{ public Carta (String p, int n)
int i=0, j; { palo = p;
cartas = new Carta[40]; numero = n;
for (j=1; i<=10; i++, j++) }
{ cartas[i]=new Carta ("Espadas", j);
} public int numero()
for (j=1; i<=10; i++, j++) { return numero; }
{ cartas[i]=new Carta ("Copas", j);
} public String palo()
for (j=1; i<=10; i++, j++) { return palo; }
{ cartas[i]=new Carta ("Bastos", j);
} public String toString()
for (j=1; i<=10; i++, j++) { return numero + " " + palo; }
{ cartas[i]=new Carta ("Oros", j); }
}
}

public void barajar()


{ ... }
public Carta devuelveCarta (int n)
{ return cartas[n]; }
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 62


Jerarqua
Composicin
class Estudiante

Composicin como mecanismo de {


public String titulacion;

reutilizacin public String [] asignaturas;


private Persona p;

Estudiante podra contener una public float calcularMatricula()


{ ... }
persona en vez de heredar de persona
public String getNombre()
Se usa la delegacin, los mtodos de { return p.getNombre();}

Estudiante que debe resolver persona public void setNombre(String n)

(getNombre) se delegan a la instancia


{ p.setNombre(n); }

interna de Persona public String getApellidos()


{ return p.getApellidos();}

Qu os parece ms cmodo, la public void setApellidos(String d)

herencia o la delegacin? { p.setApellidos(d); }

public int getEdad()


. { return p.getEdad();}

. public void setEdad(int e)


{ p.setEdad(e); }
. public int getGenero()
. { return p.getGenero();}

.
public void setGenero(int e)
{ p.setGenero(e); }
}
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 63
ndice
5. Polimorfismo
Tipos de polimorfismo
Polimorfismo de inclusin
Polimorfismo paramtrico
Sobrecarga
Coercin

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 64


Polimorfismo
Definicin
El trmino viene del griego y significa muchas formas
En lenguajes OO se podra definir como: la capacidad de una
variable de tener ms de un tipo y de una funcin de ser
aplicada sobre parmetros de distintos tipos.
Lenguajes monomrficos
Las variables slo pueden tener un tipo y las funciones slo
admitan parmetros con un nico tipo (ej. Pascal estndar)
Tipos de polimorfismo
El polimorfismo involucra distintos aspectos, de
funcionamiento similar, pero que se basan en conceptos
completamente distintos
Para intentar poner un poco de orden entre todas las
definiciones que implicaban polimorfismo Cardelli y Wegner
(1985) realizaron una clasificacin de las mismas
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 65
Polimorfismo
Tipos de polimorfismo

Paramtrico

Universal o
verdadero
De Inclusin

Polimorfismo

Sobrecarga

Ad hoc o
aparente
Coaccin

66
Polimorfismo
Tipos de polimorfismo
Polimorfismo universal o verdadero
Consiste en que pueden existir valores que pueden
pertenecer a varios tipos, y se utiliza el mismo
cdigo para tratar los diferentes tipos
Tenemos dos variantes del polimorfismo universal, el
polimorfismo paramtrico y el de inclusin

Polimorfismo ad hoc o aparente


Se utiliza distinto cdigo para tratar diferentes tipos
De esta forma una funcin polimrfica sera
implementada a travs de un conjunto de funciones
monomrficas
Dentro del polimorfismo ad hoc podemos distinguir
la sobrecarga y la coerccin
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 67
Polimorfismo
Polimorfismo de inclusin
Caractersticas
Es propio de los lenguajes orientados a objetos.
Es aquel que se consigue a travs de la herencia. Por eso se
llama tambin polimorfismo de subclases, o de herencia, o
simplemente polimorfismo
Indica que un objeto de una subclase puede utilizarse en
aquellos lugares en los que se requiere un objeto de sus
superclases
Recordemos que un objeto de la subclase incluye internamente
un objeto de la superclase

Animal listaAnimales[] = new Animal[10];


listaAnimales [0] = new Perro();
listaAnimales [1] = new Gato();
listaAnimales [2] = new Animal();

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 68


Polimorfismo
Polimorfismo de inclusin
Mtodos genricos
En lenguajes, como Java u Object Pascal (Delphi), en
los que existe una superclase comn para todas las
clases (Object), es sencillo crear mtodos genricos
que acepten parmetros de cualquier tipo o que
devuelvan valores de cualquier tipo
Simplemente los parmetros o el tipo de retorno se
especifican de tipo Object ya que todas las clases
son subclases de Object y pueden suplantarlo si es
necesario
public Object metodoGenerico(Object o)
{ }

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 69


Polimorfismo
Polimorfismo de inclusin
Colecciones y polimorfismo de inclusin
Java utilizaba hasta la versin 1.4 profusamente el
polimorfismo de inclusin en las clases destinadas a
almacenar colecciones de datos (como Vector, List,
HashTable, etc.).
As un vector se define cono un contenedor de
objetos de tipo Object, por lo que en un vector podra
ir cualquier tipo de clase

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 70


Polimorfismo
Polimorfismo de inclusin
Colecciones y polimorfismo de inclusin
Al entrar en la :Gato :Coche
Est esto permitido?
coleccin el gato
se almacena en nombre="Mich" marca = "Ford"
una variable de
tipo object

Un vector se
define :Object :Object :Object :Object :Object
internamente
como un Array nombre =
marca = "Ford"
de Object "Mich"

Al salir de la coleccin es Qu ocurre con este cdigo?


necesario hacer un typecast Coche c = (Gato) vector.get(3);
explcito para convertir el Object
en un Gato y acceder as a los :Gato
elementos especficos del Gato
nombre =
Gato g = (Gato) vector.get(1); "Mich"
System.out(g.nombre);

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 71


Polimorfismo
Polimorfismo de inclusin
Colecciones y polimorfismo de inclusin

import java.util.*;

public class ListaSinGenericidad


{
No existe seguridad de tipos en las
public static void main(String [] args) colecciones que utilizan el
{ polimorfismo de inclusin
List listaGatos = new ArrayList();
listaGatos.add(new Gato());
El type-cast es necesario para evitar
listaGatos.add(new Coche()); un error en tiempo de compilacin
Gato gato1 = (Gato)listaGatos.get(0);
Gato gato2 = (Gato)listaGatos.get(1);
} Error ClassCastException, estamos
intentando convertir un Coche en
} un Gato

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 72


Polimorfismo
Polimorfismo paramtrico
Caractersticas
Se conoce habitualmente como genericidad
Consiste en que una misma funcin es aplicada
sobre una variedad de tipos distintos
Se denomina paramtrico porque las funciones
necesitan un parmetro para saber qu tipo debe de
ser utilizado
En Java pueden definirse mtodos y clases
parametrizadas (slo a partir de la versin 1.5)
La principal ventaja de la genericidad consiste en la
posibilidad de definir colecciones de objetos con
comprobacin de tipos en tiempo de compilacin

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 73


Polimorfismo
Polimorfismo paramtrico
Colecciones y polimorfismo paramtrico

Se aade un parmetro entre los


smbolos < y > que indica el
import java.util.*;
tipo de la coleccin.

public class ListaConGenericidad


{ El mismo parmetro debe aadirse
public static void main(String [] args) en la llamada al constructor.
{
List<Gato> listaGatos = new ArrayList<Gato>();
listaGatos.add(new Gato());
Ahora el compilador hace
//listaGatos.add(new Coche()); comprobaciones en tiempo de
Gato gato1 = listaGatos.get(0); ejecucin. Esta lnea est
} comentada porque sino dara error
}
Los type-cast ya no son necesarios
para extraer elementos de una
coleccin. Existe seguridad de tipos

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 74


Polimorfismo
Polimorfismo paramtrico
Colecciones y polimorfismo paramtrico
Seguridad:
Realizan comprobaciones de tipo en tiempo de compilacin
(en una lista de gatos slo puede haber gatos)
Se evitan los fallos en tiempo de ejecucin
Claridad:
No necesitamos typecasts para sacar objetos de la
coleccin
Comprensibilidad
Las colecciones se declaran con un tipo, por lo que hace
ms claro su uso

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 75


Polimorfismo
Polimorfismo paramtrico
Creacin de clases con polimorfismo paramtrico
Los tipos genricos deben ser objetos (no tipos bsicos)
class CajaGenerica<T>
{
private T valor;

public T getValor()
{ return valor; }

public void setValor(T valor)


{ this.valor = valor; }

public static void main(String [] args)


{
CajaGenerica<Gato> cajaGato= new CajaGenerica<Gato>();
CajaGenerica<Integer> cajaInteger= new CajaGenerica<Integer>();
cajaGato.setValor(new Gato());
System.out.println("everything is ok");
//cajaInteger.setValor(new Gato()); // Error de compilacin
}
}
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 76
Polimorfismo
Polimorfismo paramtrico
Mtodos con genericidad
Eliminar de una coleccin de Strings aquellos que sean de
longitud = 4
Mtodo con polimorfismo de inclusin
static void eliminar(Collection c)
{
for (Iterator I = c.iterator(); i.hasNext(); )
if (((String) i.next()).length() == 4)
i.remove
}

Mtodo con genericidad


static void eliminar(Collection<String> c)
{
for (Iterator<String> I = c.iterator(); i.hasNext(); )
if (i.next().length() == 4)
i.remove();
}

77
Polimorfismo
Polimorfismo paramtrico
Otras ventajas de la versin 1.5
Autoboxing / autounboxing
Los tipos bsicos se convierten automticamente a sus clases
asociadas y viceversa
Foreach
Las colecciones pueden recorrerse sin usar iteradores
No hay una palabra clave foreach por compatibilidad
Ejemplo:
Sumamos de una coleccin de enteros cuntos son iguales a 5
public int antes(Collection c) public int ahora(Collection<Integer> c)
{ {
int num=0; int num=0;
for (Iterator i = c.iterator(); i.hasNext();) for (Integer i : c)
{ if (i.equals(5))
if (i.next().equals(new Integer(5))) num++;
num++; return num;
} }
return num;
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 78


Polimorfismo Paramtrico
Genericidad y subclases
Es este cdigo legal?

List<String> ls = new ArrayList<String>();


List<Object> lo = ls;

De otra forma: Si un String puede asignarse a un Object, Puede un


List<String> ser asignado a un List<Object>?

.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 79
Polimorfismo Paramtrico
Genericidad y subclases
Antes de los genricos para crear un mtodo que imprimiera todos
los elementos de una coleccin hacamos:
public void printCollection(Collection c)
{
for(Object e : c)
System.out.println(e);
}

Ahora: Es esta solucin correcta?

public void printCollection(Collection<Object> c)


{
for(Object e : c)
System.out.println(e);
}

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 80


Polimorfismo Paramtrico
Comodines
Comodines
<?>
Representa a cualquier clase. No es lo mismo que <Object>
public void printCollection(Collection<?> c)
{
for
for(Object e : c)
System.out.println(e);
}

<? extends MiClase>


Representa a cualquier subclase de MiClase, incluida la
propia MiClase
<? super MiClase>
Representa a cualquier superclase de MiClase, incluida la
propia MiClase

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 81


Polimorfismo Paramtrico
Comodines
El uso de extends o super aumenta la flexibilidad del cdigo, pero
Cundo usar extends y cundo usar super? Cundo es
adecuado usar comodines?
Principio Get y Put (Productor-Consumidor)
Utiliza el comodn extends cuando quieras slo leer valores
Utiliza el comodn super cuando quieras slo escribir valores
No utices ningn comodn cuando quieras leer y escribir valores de
una coleccin
Ejemplo
Definimos un mtodo que dada una coleccin de perros los hace ladrar
Como no vamos a escribir ningn valor en la coleccin el uso del
comodn extends flexibiliza el mtodo para usarlo con cualquier
subclase de Perro
Tiene que ser una subclase porque nos tenemos que asegurar de que
dispone del mtodo ladra
public void ladraColeccion (Collection<? extends Perro> c)
{
for(Perro p : c)
p.ladra();
}
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 82
Polimorfismo Paramtrico
Comodines
Ejemplo del API de Java
El mtodo copy de java.util.Collections copia todos los
elementos de la lista scr en la lista dest
public static <T> void copy(List<? super T> dest,
List<? extends T> src)
Explicacin
El primer <T> antes del tipo de retorno indica claramente cul
es la variable genrica del mtodo
Supongamos que T es la clase Animales
dest es una lista de Object (superclase de Animal) y src es una
lista de Perros (subclase de Animal)
De src slo leemos, luego es un extends. Por ejemplo yo
puedo sacar elementos de la lista de Perros
En dest escribimos, luego es un super. Yo puedo poner al
perro extraido anteriormente en cualquier lista de Animales o
alguna de sus superclases (como Object).

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 83


Polimorfismo Paramtrico
Comodines
Aspectos a tener en cuenta sobre los comodines:
Las colecciones definidas a travs de los comodines
<?> y <? extends Clase> son de solo lectura
Cmo podramos poner un elemento en la coleccin
c1 si no sabemos de que tipo es. Lo mismo pasa con
c2, sabemos que es una subclase de Perro pero no
sabemos cul
Si fuera un <? super Clase> no habra problema en
meter en la coleccin objetos de Clase o cualquiera
de sus subclases
public void printCollection(Collection<?> c) public void ladraColeccion (Collection<? extends Perro>
{ c)
for(Object e : c) {
System.out.println(e); for(Perro p : c)
} p.ladra();
}
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 84
Polimorfismo Paramtrico
Comodines
Firmas complejas de mtodos:
Las firmas de los mtodos pueden llegar a complicarse en
demasa
public static <T extends Comparable<? super T>>
void sort(List<T> list)
public static <T extends Object & Comparable<?
super T>> T max(Collection<? extends T> coll)
En ambos casos se utiliza la variable que define el tipo
genrico para especificar con detalle lo que debe cumplir
ese tipo genrico T. En los posteriores usos de T se
asume que cumple todo lo que hemos establecido
Referencia:
Effective Java (2nd Edition). Chapter 5: Generics. URL:
http://java.sun.com/docs/books/effective/generics.pdf

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 85


Polimorfismo
Polimorfismo paramtrico
El proceso de borrado (erasure)
Java realiza un proceso denominado erasure en el cual toda la
informacin acerca de la genericidad no se propaga a los bytecodes
De esta forma la genericidad funciona slo en tiempo de compilacin
pero no en tiempo de ejecucin
Consecuencias
La genericidad no afecta al rendimiento
No es posible la sobrecarga de funciones parametrizadas
unMetodo(List<Integer> x) y unMetodo(List<String> x) son iguales en
tiempo de ejecucin ya que la informacin parmetrica se elimina
Las colecciones parametrizadas pueden corrormperse utilizando
reflexin
Por ejemplo un atributo List<Integer> obtenido a travs de
getDeclaredFields es slo un List
Motivacin del erasure
Compatibilidad: el bytecode no generificado no se diferencia del que si
lo est
Evolucin, no revolucin: podemos generificar un API (por ejemplo
Collections) y no actualizar los clientes que lo usan
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 86
Polimorfismo
Sobrecarga
Caractersticas
La sobrecarga (overloading) consiste en utilizar el
mismo nombre para denotar funciones distintas.
Para saber que funcin utilizar se utiliza el contexto
de cada caso en particular (los parmetros o la clase
en la que est definida).
El polimorfismo es slo aparente (ad hoc), no existe
una funcin que acepte distintos parmetros, sino
distintas funciones adaptadas a cada tipo de
parmetro pero que nos dan la impresin de ser la
misma porque comparten el mismo nombre.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 87


Polimorfismo
Sobrecarga
Sobrecarga entre clases:
La sobrecarga entre clases ocurre cuando clases distintas
responden al mismo tipo de mensaje, es decir, distintas clases
tienen mtodos con el mismo nombre.
Esta situacin es muy comn en los lenguajes orientados a
objetos porque permite definir nombres comunes a operaciones
comunes y facilita el aprendizaje de las bibliotecas de
funciones.
Por ejemplo, en Java el nombre isEmpty es compartido por
clases como Vector, Hashtable o Rectangle. En las dos
primeras devuelve true si la coleccin est vaca, en la ltima
devuelve true si el rea del rectngulo es cero.
Como vemos, la sobrecarga entre clases suele implicar que
existe una cierta relacin semntica entre los mtodos
sobrecargados, aunque esto no tiene porque ser siempre cierto.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 88
Polimorfismo
Sobrecarga
Sobrecarga paramtrica:
La sobrecarga paramtrica ocurre dentro de una misma clase
cuando varios mtodos comparten el mismo nombre pero se
diferencian por su nmero y tipo de parmetros.
Es importante destacar que los mtodos no tienen porque ser
definidos todos en la misma clase sino que tambin se pueden
sobrecargar mtodos heredados de superclases.
Este tipo de sobrecarga no es exclusivo de los lenguajes
orientados a objetos y tambin aparece en los lenguajes
imperativos tradicionales
La sobrecarga paramtrica es muy utilizada en los
constructores para ofrecer distintas vas en las que crear un
objeto. Por ejemplo podemos crear un objeto esfera con
parmetros por defecto, especificando todos o parte de sus
parmetros o crearlo a partir de otro objeto esfera.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 89


Polimorfismo
Sobrecarga
Sobrecarga de operadores:
Consiste en darle varios significados a los
operadores
Por ejemplo en Java, + significa sumar nmeros
pero tambin concatenar Strings
Otros lenguajes permiten a los usuarios sobrecargar
libremente los operadores (C++)
Java no permite la sobrecarga de operadores por
parte de los usuarios (por motivos de claridad)

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 90


Polimorfismo
Sobrecarga
Es el siguiente cdigo vlido?
int metodoX (); { }
float metodoX(); { }

De otra forma: El tipo de retorno se tiene en cuenta a la hora de


resolver la sobrecarga?

.
.
.
.
.
.
.
.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 91


Polimorfismo
Sobrecarga
Sobreescritura (overriding)
Podra considerarse como un tipo de sobrecarga
entre clases
Aparece cuando una subclase define un mtodo con
el mismo nombre, tipo de retorno y parmetros que
una superclase
El comportamiento adecuado es que el mtodo de la
subclase sobreescriba al mtodo de la superclase
La sobreescritura implica que existe sobrecarga
entre clases (superclase y subclase), si bien lo
contrario no tiene porque ser cierto.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 92


Polimorfismo
Sobrecarga
Tipos de sobreescritura:
Sobreescritura de reemplazo
El mtodo de la subclase reemplaza por completo el mtodo
de la superclase
Sobreescritura de refinamiento
El mtodo de la subclase es una forma refinada del mtodo
de la superclase (se utiliza el cdigo de la superclase pero
se aaden algunas caractersticas propias)
Para acceder a la versin del mtodo de la superclase se
utiliza el puntero super (que apunta a la superclase) seguido
del nombre del mtodo. Por ejemplo, super.metodoX()
Al contrario de la llamada super de los constructores, la
llamada super en los mtodos sobreescritos no tiene porque
aparecer en primer lugar

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 93


Polimorfismo
Sobrecarga
Caracterstica importante de la sobreescritura
En la sobrecarga la decisin de qu mtodo utilizar
se hace en tiempo de compilacin
En la sobreescritura, la decisin de qu mtodo
utilizar (si el de la superclase o el de la subclase) se
toma en tiempo de ejecucin
Esto se debe a que en tiempo de compilacin no
sabemos si una variable definida con el tipo de la
superclase alberga una instancia de la superclase o
una instancia de alguna de sus subclases.
Volveremos a este tema a la hora de hablar de la
ligadura dinmica.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 94


Polimorfismo
Sobrecarga
Ejemplo de sobreescritura
abstract class Personal
{
protected long base;
protected long anhos;

long sueldo()
{ return base + (10000 * anhos); }
}

class A extends Personal Sobreescritura


{ de reemplazo
int numProyectos;
long sueldo()
{ return (100000 * numProyectos); }
}

class B extends Personal


{
long extra;
long sueldo()
{ return super.sueldo() + extra; }
}

class C extends Personal


Sobreescritura de
{ ... }
refinamiento
class D extends Personal
{ ... }

95
Polimorfismo
Sobrecarga
Especificadores de visibilidad en sobrecarga
El especificador de visibilidad de un mtodo que
sobrescribe a otros debe proporcionar por lo menos
la misma visibilidad que el mtodo sobrescrito.
Es decir:
Si el mtodo sobrescrito tena visibilidad public, el mtodo
que sobreescribe debe ser public.
Si el mtodo sobrescrito tena visibilidad protected, el
mtodo que sobreescribe debe ser public o protected.
Si el mtodo sobrescrito tena visibilidad package, el mtodo
que sobreescribe no puede ser private.
No se especifica nada si el mtodo sobreescrito tena
visibilidad private ya que estos mtodos no pueden
ser sobrescritos
96
Polimorfismo
Coercin
Coercin (o coaccin)
Es una operacin semntica por la cual se convierte un
argumento a el tipo esperado por una funcin para evitar que se
produzca un error de tipos.
Las coerciones pueden hacerse estticamente, insertndolas
entre los argumentos y las funciones en tiempo de compilacin
(seran los conocidos type cast o conversiones de tipos), o
pueden ser determinadas dinmicamente por tests en tiempo de
ejecucin sobre los argumentos.
Suele ser muy comn en todo tipo de lenguajes, incluso en los
fuertemente tipados, para evitar errores triviales con los tipos.
Ejemplo: Una funcin que acepta parmetros float aceptar
sin problemas que le pasemos un int, simplemente convertir
ese int a un float en tiempo de ejecucin
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 97
ndice
6. Tipificacin
Introduccin
Comprobacin de tipos
Esttico
Estricto o fuerte
Dinmico

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 98


Tipificacin
Introduccin
Tipos
Definicin:
un tipo es una caracterizacin precisa de las propiedades
estructurales y de comportamiento que comparten una serie de
entidades
Objetivo principal: Nocin de congruencia
La concatenacin de cadenas devuelve una cadena, contar los
caracteres de una cadena devuelve un entero, etc.
Permiten detectar errores en un programa y facilitan el
funcionamiento interno de los compiladores
En los lenguajes OO una clase es un tipo pero hay que tener
cuidado:
Hay tipos que no son clases (los tipos bsicos como int, float, etc.)
En ocasiones distintas clases implementan el mismo tipo de datos
(el tipo List es implementado por dos clases distintas ArrayList y
LinkedList)
Puede ocurrir que una subclase no sea un subtipo. Ver ms
informacin en el principio de sustitucin de Liskov (principios de
diseo)
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 99
Tipificacin
Comprobacin de tipos
Comprobacin de tipos
Podemos distinguir tres formas de comprobar los
tipos: tipado esttico, tipado estricto y tipado
dinmico.

Tipado esttico
Consiste en que el tipo exacto de cada expresin
puede ser determinado en tiempo de compilacin
mediante un anlisis esttico del programa.
El tipado esttico permite detectar incongruencias en
tiempo de compilacin pero, sin embargo, puede
llegar a ser muy restrictivo.
Un ejemplo de tipado esttico sera el lenguaje
Pascal estndar.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 100
Tipificacin
Comprobacin de tipos
Tipado estricto o fuerte
Es un requisito ms dbil que el tipado esttico y
consiste en que todas las expresiones de tipos
tienen que ser consistentes en tiempo de
compilacin.
El compilador garantizar que el programa se
ejecutar sin errores de tipos.
Muchas veces se incluye el tipado esttico y el
tipado estricto dentro de una misma categora.
El tipado fuerte es propio de los lenguajes orientados
a objetos como Java, Object Pascal o C++, aunque el
nivel de exigencia en cada uno de ellos puede variar.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 101
Tipificacin
Comprobacin de tipos
Consistencia (definida a travs de tres restricciones):
Restriccin de declaracin.
Todas las entidades del lenguaje (variables, objetos, atributos)
deben tener un tipo declarado (que como hemos visto puede ser un
tipo bsico o una clase). Adems cada mtodo o funcin debe
declarar cero o ms argumentos formales especificando un tipo
para cada uno.
Restriccin de compatibilidad.
En cada asignacin x = y, y en cada llamada a una rutina en que se
usa y como argumento real para el argumento formal x, el tipo de la
fuente y debe ser compatible con el tipo de destino x. La definicin
de compatibilidad se basa en la herencia, y es compatible con x si
es descendiente de x (es lo que habamos visto en el tema anterior
como polimorfismo de inclusin).
Restriccin de llamada a caracterstica.
Para poder llamar a una caracterstica (atributo o un mtodo) f
desde la clase X, f tiene que estar definida en X o en uno de sus
antecesores.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 102
Tipificacin
Comprobacin de tipos
Cul es el resultado de la ejecucin del siguiente cdigo?

class Animal
{
// El mtodo ladra no est definido en Animal
}
class Perro extends Animal
{
public void ladra() { ... }
}

...
Animal unAnimal = new Perro();
unAnimal.ladra();
...

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 103


Tipificacin
Comprobacin de tipos
Concepto de pesimismo en el tipado fuerte
Existen ciertas operaciones con los tipos que pueden ser
vlidas, pero si no hay una seguridad absoluta de que lo son
entonces es mejor no permitirlas.
La idea subyacente es que es mejor detectar los posibles
errores en tiempo de compilacin y no en tiempo de ejecucin
(ya que son una mayor molestia para el usuario de la
aplicacin).

Ejemplo de pesimismo
Al ejecutar unAnimal.ladra() si en unAnimal tenemos un Perro la
cosa funcionara.
Pero no hay nada que garantice que en unAnimal hay un perro
ya que puede haber otro tipo de animales que no ladran (gatos,
canarios, etc.)

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 104


Tipificacin
Comprobacin de tipos
Soluciones al pesimismo
Hacer un type-cast explcito
La siguiente instruccin funcionara sin problemas:
((Perro) unAnimal).ladra()
Como sabemos que hay un perro hacemos un type-cast explcito y
llamamos al mtodo ladra
Problema: si no hay un perro obtenemos un error de ejecucin. El
compilador se desentiende porque la responsabilidad de que los type-cast
explcitos sea correcta es del programador
Usar funciones RTTI (Run-Time Type Information)
Nos podemos asegurar que en unAnimal hay un perro con sentencias
como: if (unAnimal instanceof Perro) {...}.
Hay que tener cuidado porque este tipo de instrucciones suele dar lugar a
cdigo muy poco OO (ver ejemplo en lig. dinmica).
Maximizar el interfaz de Animal incluyendo el mtodo ladra.
Los animales que no sean perros devolveran algo del estilo no ladro
Se trata de un compromiso entre la flexibilidad que da trabajar con
superclases genricas y la necesidad de que los mtodos especficos no
suban en la jerarqua de herencia hacia clases ms generales (ver ejemplo
en patrn composicin).
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 105
Tipificacin
Comprobacin de tipos
Ventajas del tipado fuerte:
Fiabilidad.
Permite detectar en tiempo de compilacin errores que de otra manera slo
se manifestaran en tiempo de ejecucin, y slo en ciertas ejecuciones.
Es esencial detectar cuanto antes los errores, pues el coste de la
correccin es mucho mayor cuanto ms se demora la deteccin.
Legibilidad.
Declarar una entidad y una funcin con un cierto tipo es una potente forma
de trasmitirle al lector del cdigo informacin sobre lo que se intenta que
dicho software haga. Esto lo apreciarn sobre todo los encargados de
mantener ese software.
Eficiencia.
El tipado esttico es el tipo ms eficiente de tipado ya que permite conocer
el tiempo de compilacin el tipo exacto del elemento y efectuar las
optimizaciones necesarias.
El tipado estricto de los lenguajes orientados a objetos no es tan eficiente
pero permite restringir el conjunto de tipos posibles a unos pocos y, por
tanto, generar cdigo casi tan eficiente como en el tipado esttico.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 106


Tipificacin
Comprobacin de tipos
Tipado dinmico
Todas las comprobaciones de tipos se realizan en tiempo de ejecucin
Para tratar los posibles errores en tiempo de ejecucin es necesario
desarrollar sistemas que los manejen, como la utilizacin de
excepciones.
Un ejemplo tpico de un lenguaje con tipado dinmico es Smalltalk.
Principal ventaja: flexibilidad
Los partidarios del tipado dinmico se acogen frecuentemente a la idea de
la flexibilidad para defenderlo.
Esto sera cierto para los lenguajes con tipado esttico, pero los lenguajes
con un tipado fuerte o estricto incluyen la suficiente flexibilidad para
permitir que los tipos no sean una camisa de fuerza beneficindose de la
fiabilidad, legibilidad y eficiencia que aportan.
Tendencia actual:
Tal y como se muestra en los nuevos lenguajes aparecidos en los ltimos
aos (Delphi, Java y C#), es incluir un tipado estricto.
Pero el tipado dinmico es popular en lenguajes de script
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 107
ndice
7. Ligadura dinmica
Funcionamiento
Implementacin
Eficiencia

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 108


Ligadura dinmica
Ligadura
La ligadura se encarga de ligar o relacionar la llamada a un
mtodo (mensaje) con el cuerpo del mtodo que se ejecuta
finalmente.
Existen dos tipos de ligadura: esttica y dinmica
Ligadura esttica (o temprana):
Consiste en realizar el proceso de ligadura en tiempo de
compilacin segn el tipo declarado del objeto al que se manda el
mensaje.
La utilizan (en Java) los mtodos de clase y los mtodos de
instancia que son privados o final (ya que estos ltimos no pueden
ser sobreescritos).
Ligadura dinmica (o tarda):
Consiste en realizar el proceso de ligadura en tiempo de ejecucin
siendo la forma dinmica del objeto la que determina la versin del
mtodo a ejecutar.
Se utiliza en todos los mtodos de instancia en Java que no son ni
privados ni final.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 109


Propiedades bsicas
Ligadura dinmica
Uso conjunto de herencia, polimorfismo y ligadura dinmica

Figura Calculo

X: int
Y: int
calculaAreaFiguras(Figura[] ListaFiguras)
calcularArea(): float
calcularPerimetro(): float

Polimorfismo
ListaFiguras = new Figura[10];

Circulo Rectangulo ListaFiguras [0] = new Circulo ();


ListaFiguras [1] = new Rectangulo ();
radio: int largo: int
ListaFiguras [2] = new Circulo
Cuadrado(); ();
ancho: int
calcularPerimetro(): float
calcularArea(): float calcularPerimetro(): float Ligadura dinmica
calcularArea(): float
ListaFiguras [0].calculaArea(); // Circulo
ListaFiguras [1].calculaArea(); // Rectangulo
float calculaArea() float calculaArea() ListaFiguras [2] .calculaArea(); // Circulo
{ return Math.PI * radio * radio; } { return largo * ancho; }

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 110


Propiedades bsicas
Ligadura dinmica
Uso conjunto de herencia, polimorfismo y ligadura dinmica

Figura Calculo
Cuadrado
X: int
lado: int
Y: int
calculaAreaFiguras(Figura[] ListaFiguras)
calcularPerimetro(): float
calcularArea(): float
calcularArea(): float
calcularPerimetro(): float

float calculaArea() Polimorfismo


{ return lado * lado; }
ListaFiguras = new Figura[10];

Circulo Rectangulo ListaFiguras [0] = new Circulo ();


ListaFiguras [1] = new Rectangulo ();
radio: int largo: int
ListaFiguras [2] = new Circulo
Cuadrado(); ();
ancho: int
calcularPerimetro(): float
calcularArea(): float calcularPerimetro(): float Ligadura dinmica
calcularArea(): float
ListaFiguras [0].calculaArea(); // Circulo
ListaFiguras [1].calculaArea(); // Rectangulo
float calculaArea() float calculaArea() ListaFiguras [2] .calculaArea(); // Circulo
Cuadrado
{ return Math.PI * radio * radio; } { return largo * ancho; }

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 111


Propiedades bsicas
Ligadura dinmica
Uso conjunto de herencia, polimorfismo y
ligadura dinmica
Podemos escribir cdigo que no haga referencia a
las subclases concretas pero que utilice cdigo de
stas (como el mtodo calcularArea)
Al no hacer referencia a las subclases el cdigo
funcionar igual (sin necesidad de modificarlo) si
creamos una nueva subclase (Cuadrado). Ver
principio abierto-cerrado
En resumen:
Estamos creando cdigo que ser capaz de trabajar, sin
modificarlo, con cdigo futuro que an no est escrito
Flexibilidad, Escalabilidad, Extensibilidad, etc.
Realmente no conocemos quin est haciendo en trabajo
Abstraccin, Seguridad, Facilidad de mantenimiento, etc.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 112


Ligadura dinmica
Ejemplo
abstract class Personal ...
{ A PA = new A();
protected long base; B PB = new B();
protected long anhos; C PC = new C();
private String nombre; D PD = new D();
Personal [] P = new Personal[4];
final String getNombre()
{ return nombre; } PA.setNombre("A");
PA.base = 100000;
final void setNombre (String s) PA.anhos = 1;
{ nombre = s; } PA.numProyectos = 5;

long sueldo() PB.setNombre("B");


{ return base + (10000 * anhos); } PB.base = 100000;
PB.anhos = 1;
long pagaExtra () PB.extra = 50000;
{ return base; }
} PC.setNombre("C");
PC.base = 100000;
class A extends Personal Sobreescritura PC.anhos = 1;
{ de reemplazo
int numProyectos; PD.setNombre("D");
long sueldo() PD.base = 100000;
{ return (100000 * numProyectos); } PD.anhos = 1;

float rendimiento() P[0] = PA; Polimorfismo


{ return numProyectos / anhos; } P[1] = PB;
} P[2] = PC; de inclusin
P[3] = PD;
class B extends Personal
{ for (int i=0; i<=3; i++)
long extra; System.out.println(
long sueldo() P[i].getNombre()
{ return super.sueldo() + extra; } + " = " + P[i].sueldo());
} ...

class C extends Personal Sobreescritura de /* Resultados


{ ... } A = 500000 Ligadura
refinamiento
B = 160000 dinmica
class D extends Personal C = 110000
{ ... } D = 110000 */
113
Ligadura dinmica
Funcionamiento
Empleo de funciones RTTI como alternativa:
long sueldo()
{
if (this instanceof A)
return (100000 * ((A)this).numProyectos);
else if (this instanceof B)
return (base + (10000 * anhos)) + ((B)this).extra;
else return base + (10000 * anhos);
}

Funciona pero es un antipatrn OO


El cdigo para calcular el sueldo del personal A no est en la
clase A
Cada vez que se aada una nueva subclase hay que acordarse
de modificar el if (ver principio abierto-cerrado)
Las funciones RTTI no son incorrectas pero s es fcil que
lleven a construcciones que son poco orientadas a objetos.
Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 114
Ligadura dinmica
Funcionamiento
Cul es el resultado de la ejecucin del siguiente cdigo?
class Padre
{
int x = 5;

static void f ()
{ System.out.println( "Padre.f" ); }
}

class Hijo extends Padre


{
int x = 10;

static void f ()
{ System.out.println( "Hijo.f" ); }

public static void main (String [] args )


{ Hijo h = new Hijo();
h.f(); // Hijo.f
System.out.println(h.x);// 10

Padre p = new Hijo();


p.f(); // Padre.f
System.out.println(p.x);// 5
}
}

;)

115
Ligadura dinmica
Implementacin
Caractersticas
Puede variar de un lenguaje a otro pero bsicamente presentan
unas caractersticas comunes.
Mtodos que necesitan ligadura dinmica
Deben presentar ligadura dinmica slo aquellos que pueden ser
redefinidos.
Por ejemplo, en Java los mtodos de clase y los mtodos de
instancia privados y/o finales no presentan ligadura dinmica.
En Java si no se especifica nada se entender que el mtodo puede
ser redefinido y por tanto debe presentar ligadura dinmica.
En otros lenguajes como Object Pascal o C++ los mtodos por
defecto presentan ligadura esttica, si queremos que su ligadura
sea dinmica es necesario incluirle la directiva virtual (por eso los
mtodos con ligadura dinmica se conocen como mtodos
virtuales). El mtodo que sobreescribe de incluir la directiva
override

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 116


Ligadura dinmica
Implementacin
Caractersticas (cont.)
Tablas de mtodos virtuales
La tabla que contiene la definicin de la clase y que apunta
al cdigo de los mtodos de instancia se divide en dos: una
tabla para los mtodos no virtuales y una tabla de mtodos
virtuales (VMT) que incluye una entrada por cada mtodo
virtual de la clase.
Los objetos de una misma clase comparten una misma VMT.
Una vez que a un mtodo se le asigna una posicin en la
tabla virtual, esta posicin no cambia en las VMTs de las
clases derivadas.
Los punteros de los mtodos que no son virtuales y los
mtodos virtuales que no han sido sobreescritos apuntan al
cdigo de la superclase. Por otro lado los mtodos virtuales
sobreescritos en la subclase y los mtodos virtuales propios
de dicha clase apuntan a cdigo nuevo definido en la
subclase.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 117


Ligadura dinmica
Implementacin
Objeto de la clase Personal
Personal()
Puntero a Informacin de la clase
la clase Personal
getNombre()
Puntero del constructores
objeto base
... setNombre(String)
anhos met. no virtuales
VMT sueldo()
nombre
pagaExtra()

Objeto de la clase A
Apuntan a la misma
direccin que los mtodos
de la superclase

A()
Puntero a Informacin de la
la clase clase A
getNombre()
Puntero del constructores
objeto base
... setNombre(String)
anhos met. no virtuales
VMT sueldo()
nombre
pagaExtra()
numProyectos
rendimiento()

Apuntan a
cdigo nuevo
118
Ligadura dinmica
Implementacin
Ejemplo de VMTs
Las VMTs de las clases C y D para los mtodos sueldo() y pagaExtra()
apuntarn al cdigo incluido en la clase Personal.
En la clase A slo la entrada de pagaExtra() apunta a Personal, ya que
no ha sido redefinido, sin embargo la entrada de sueldo() apuntar a la
versin del mtodo incluida en la subclase A. Lo mismo para B.
Los mtodos getNombre y setNombre no se incluyen en la tabla de
mtodos virtuales porque se han definido final.
El mtodo rendimiento() definido en la clase A tambin debe ser
incluido en la VMT ya que, aunque no es redefinido por ninguna clase,
puede ser redefinido en un futuro (no es privado ni final).

Proceso seguido en la llamada x.sueldo()


Cogemos el puntero del objeto que apunta a la VMT y miramos en esa
tabla la entrada 1 que corresponde al mtodo sueldo(), utilizamos el
puntero de esta tabla para saltar a la rutina correspondiente y la
ejecutamos.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 119


Ligadura dinmica
Implementacin
VMT C abstract class Personal
{
1 long sueldo() ...
long sueldo()
2 long pagaExtra() { return base
+ (10000 * anhos); }

long pagaExtra()
{ return base; }
}

VMT D
class A extends Personal VMT A
1 long sueldo() {
... long sueldo() 1
2 long pagaExtra() long sueldo()
{ return long pagaExtra() 2
(100000*numProyectos);}
float rendimiento() 3
float rendimiento()
{ return
numProyectos/anhos;}
}

class B extends Personal VMT B


{
... long sueldo() 1
long sueldo()
{ return super.sueldo() long pagaExtra() 2
+ extra; }
}

120
Ligadura dinmica
Eficiencia
Principal inconveniente de la ligadura dinmica: la eficiencia.
Llamadas a mtodos virtuales
Ocupan ms cdigo que la llamada a un mtodo esttico y consume
ms tiempo
Aunque esta penalizacin es pequea y est acotada por una
constante (es independiente del nivel de herencia en el que nos
encontremos)

Llamadas a mtodos no virtuales


Se puede saltar directamente al cdigo de la funcin sin necesidad de
acceder a una VMT.
Adems tambin se puede transformar una llamada a un mtodo por
una llamada inline.
Una llamada inline lo que hace es eliminar la llamada al mtodo (con su
correspondiente paso de parmetros) y lo reemplaza por una copia de las
instrucciones que existen en el cuerpo del mtodo.
Las llamadas inline son por tanto muy rpidas pero penalizan el tamao del
cdigo, por lo que un compilador inteligente slo debera convertir en inline
mtodos pequeos.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 121


Ligadura dinmica
Eficiencia
Consecuencias de la perdida de eficiencia
En muchos lenguajes se limita el uso de la ligadura dinmica.
Sin embargo, limitar la capacidad de ligadura dinmica de las clases es
limitar su reusabilidad.
Java permite la definicin de mtodos finales con dos objetivos:
Proteger el funcionamiento del mtodo contra posibles sobreescrituras de
las subclases.
Desactivar la ligadura dinmica porque se sabe a ciencia cierta que ese
mtodo no va a ser sobreescrito y de esta forma se genera cdigo ms
eficiente.
En ambos casos en programador tiene que saber que est limitando la
reutilizacin de la clase
Los mtodos getNombre() y setNombre() se declaran finales porque no
tiene sentido su sobreescritura.
Sin embargo, si aparece un nuevo tipo de personal definido por la subclase
Robot, puede ser adecuado redefinir el mtodo getNombre para devolver un
nmero de serie, sin embargo al ser declarado final esto no es posible.
Los mtodos final atentan contra el principio abierto-cerrado porque
impiden redefiniciones no previstas de la clase (ver patrn mtodo plantilla
para ver un uso adecuado de mtodos final).

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 122


Ligadura dinmica
Eficiencia
Consecuencias de la perdida de eficiencia (cont.)
Enfoque deseable
Nunca un programador debe incluir ligadura esttica por motivos
de optimizacin.
Un compilador lo suficientemente inteligente podra detectar
cuando no es necesaria la utilizacin de ligadura dinmica y
optimizar el cdigo consecuentemente.
Un caso ms grave puede ocurrir en C++ u Object Pascal.
En estos lenguajes se utiliza la ligadura esttica por defecto, y es
responsabilidad del programador el indicar que los mtodos deben
usar ligadura dinmica mediante la sentencia virtual.
Por ejemplo si no indicamos que el mtodo sueldo() es virtual, la
llamada x.sueldo(), siendo Personal x = new A(), a pesar de
contener una instancia de la clase A, ejecutar el mtodo contenido
en la clase Personal. Este funcionamiento es claramente errneo
pero es fcil que ocurra en estos entornos.
NOTA IMPORTANTE: La ligadura esttica slo es correcta
cuando su efecto sea idntico al de la ligadura dinmica.

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 123


Bibliografa
Bibliografa fundamental
Booch, G. Anlisis y diseo orientado a objetos, 2 ed., Addison-Wesley / Daz de Santos,
Wilmington, Delaware, USA, 1996.
Budd, T. Understanding object-oriented programming with Java, Addison-Wesley,
Reading, MA, 1998.
Cardelli, L., Wegner, P. On understanding types, data abstraction, and polimorphism,
Computing Surveys, vol. 17, no. 4, 1985.
Graham, I. Mtodos orientados a objetos, 2 ed., Addison-Wesley / Daz de Santos,
Wilmington, Delaware, USA, 1996.
Meyer, B. Construccin de software orientado a objetos, Prentice Hall, Madrid, 1999.
McLaughlin, B., Flanagan, D. Java 1.5 Tiger: A Developers Notebook, OReilly, Sebastopol,
CA, 2004
Bibliografa complementaria
Craig, I. The Interpretation of Object-Oriented Programming Languages, Springer-Verlag,
London, 1999.
Meyer, B. Overloading vs. object technology, Journal of Object-Oriented Programming,
Oct-Nov, 2001.
Marteens, I. La cara oculta de Delphi 4, Danysoft Internacional, Madrid, 1998.
Bibliografa en Internet
Ellmer, E. Basic Principles and Concepts of Object-Orientation (1993).
URL: http://citeseer.nj.nec.com/ellmer93basic.html
Gosling, J., Joy, B., Steele, G., & Bracha, G. The JavaTM Language Specification (2nd
Edition). URL: http://java.sun.com/docs/books/jls/
Lindholm, T & Yellin, F. The JavaTM Virtual Machine Specification (2nd ed.).
URL: http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html

Eduardo Mosqueira Rey Departamento de Computacin Universidade da Corua 124

Você também pode gostar