Sei sulla pagina 1di 83

Tema 2.

Herencia y Polimorfismo
Esquema
2.1. Introduccin
2.2. Herencia
2.2.1. Concepto de herencia
2.2.2. Enmascaramiento de variables y sobrescritura de
mtodos
2.2.3. Jerarquas de clases
2.2.4. Organizacin de jerarquas de clases (paquetes)
2.2.5. Polimorfismo
2.3. Mecanismos adicionales de abstraccin basados en
herencia
2.3.1. Clases y mtodos abstractos
2.3.2. Interfaces
2.4. Genricos
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

Tema 2. Herencia y Polimorfismo


Lectura recomendada
- Muoz Caro C., Nio A. y Vizcano Barcel A. Introduccin a
la programacin con orientacin a objetos. Captulo 8.
Prentice-Hall, 2002. Reimpresin 2007.
- P.S. Nair. Java. Programming Fundamentals. Captulos 6 y 7.
Ed. CRC Press (Taylor & Francis Group), 2009. ISBN-13:9781-4200-6547-3
- Schildt H. Java: The complete reference. 8th edition,
Captulo 14: Generics. Mc Graw Hill, 2011 ISBN: 978-0-07160631-8

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.1. Introduccin
Las tres caractersticas fundamentales que definen la
programacin orientada a objetos son: encapsulacin,
herencia y polimorfismo.
Encapsulando aumentbamos la cohesin y disminuamos el
acoplamiento en los programas, lo que se traduce en una
mayor reutilizabilidad y fiabilidad del software, mayor facilidad
de desarrollo, de pruebas y de mantenimiento (aumento de la
calidad del software).
Otra caracterstica bsica de la orientacin a objetos es la
herencia. La herencia es un
mecanismo de abstraccin
consistente en la capacidad de derivar nuevas clases a partir
de otras ya existentes.
Otra caracterstica clave de la orientacin a objetos es el
polimorfismo. El polimorfismo permite que diferentes objetos
puedan responder al mismo mensaje en diferentes formas
(Arnow y Weiss, 1998). Usando polimorfismo podemos tratar
de forma unificada diferentes clases relacionadas por herencia.
Como veremos, el polimorfismo involucra la denominada
sobrescritura de mtodos y la utilizacin de referencias.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.2. Herencia (I)


La herencia es una tcnica de desarrollo de software muy
potente y, como hemos visto, una caracterstica que define la
programacin orientada a objetos. La herencia relaciona los
datos y mtodos de clases nuevas con los de clases ya
existentes, de forma que la nueva clase se puede entender
como una extensin de la antigua. En cualquier caso, la nueva
clase es un tipo particular de la clase original.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.2.1. Concepto de Herencia (I)


Como ya hemos indicado, la herencia en programacin
orientada a objetos permite crear una clase nueva a partir de
otra ya existente. La nueva clase contendr automticamente
algunos o todos los atributos (variables) y procedimientos
(mtodos) de la clase original. El diseador/a de software
puede aadir nuevas variables y mtodos a la clase nueva , o
bien modificar las variables y mtodos heredados para definir
de manera apropiada la nueva clase.
Ejemplo de herencia usando una clasificacin taxonmica

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.2.1. Concepto de Herencia (II)

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.2.1. Concepto de Herencia (III)


El proceso de derivacin de una clase nueva por herencia
corresponde a la existencia de una relacin particular entre las
dos clases: la relacin es-un que vimos en el captulo anterior.
La clase derivada es una versin ms especfica, un tipo
particular, de la original. As, todos los ejemplares de la clase
nueva pertenecen al tipo de la clase antigua, pero no al revs.
Como notacin, indiquemos que la clase original que se usa
para derivar una clase nueva se denomina clase padre,
superclase, clase base o ascendiente. La clase derivada se
llama clase hija, subclase o descendiente.
En Java se usa la palabra reservada extends para indicar que
una clase nueva est siendo derivada de (es decir que extiende
a) otra.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.2.1. Concepto de Herencia (IV)

Sintaxis bsica:
class clase_hija extends clase_padre {
--- contenido de la clase --}

Por ejemplo, si existe una clase Vehculo y queremos derivar una


nueva clase Coche haramos,
class Coche extends Vehiculo {
--- contenido de la clase --}

La clase hija automticamente hereda los mtodos y variables de


la clase clase_padre. Es como haber copiado el cdigo de la clase
padre y haberlo pegado en la clase hija.Las variables y mtodos
heredados pueden usarse en la clase clase_hija como si hubieran
sido declarados localmente en dicha clase.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

2.2.1. Concepto de Herencia (V)


Las variables y mtodos heredados retienen sus caractersticas de
visibilidad originales en la subclase.
La herencia acta en una direccin: de la clase padre a la clase hija.
Esto implica que las variables y los mtodos nuevos declarados en la
clase hija no pueden usarse en la clase padre.
Desde un punto de vista general la herencia puede ser mltiple o
simple:
Clase Padre_1

Clase Padre_2

Clase Hija

Herencia mltiple
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

Clase Padre

Clase Hija

Herencia simple
9

2.2.1. Concepto de Herencia (VI)

En Java, slo es posible la herencia simple. C++ permite herencia


mltiple.

Las variables y los mtodos que se heredan vienen controlados


por los modificadores de visibilidad:
Los miembros con visibilidad public se heredan
Los que tienen visibilidad private no se heredan.
El modificador protected establece un nivel intermedio de
proteccin entre un acceso public y uno private. Los
miembros (mtodos y variables) de una superclase o clase
padre etiquetados como protected son accesibles para las
subclases (clases hijas) y las otras clases del mismo paquete

Ejemplo de herencia. Sea un programa que maneja publicaciones


y que tiene que trabajar con tesis doctorales. Todas las tesis son
un tipo particular de publicacin (herencia). Las publicaciones,
entre otros atributos, estn caracterizadas por el ttulo, los autores
y el ao de publicacin. A su vez, las tesis tendrn tambin estos
atributos generales. Algo que distingue una tesis de otro tipo de
publicacin es que se presenta en un departamento universitario.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

10

2.2.1. Concepto de Herencia (VII)


Diagrama UML:
Publicacion
#titulo:String
#autores:String
#fecha_publicacion:int[ ]
+Publicacin (titulo:String, autores:String, dia:int, mes:int, agno:int)
+devolver_titulo():String
+devolver_autores ():String
+devolver_fecha():int[]

Tesis
#departamento:String
+Tesis(titulo:String, autores:String, departamento:String, dia:int, mes:int, agno:int)
+devolver_departamento():String

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

11

2.2.1. Concepto de Herencia (VIII)

Cdigo Java:
class Publicacion {
protected String titulo;
protected String autores;
protected int [ ] fecha_edicion=new int [3];
public Publicacion (String titulo, String autores, int dia,
int mes, int agno) {
this.titulo=titulo;
this.autores=autores;
fecha_edicion [0]=dia;
fecha_edicion [1]=mes;
fecha_edicion [2]=agno;
}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

12

2.2.1. Concepto de Herencia (VIII)

Cdigo Java de la clase publicacin (continuacin):

public String devolver_titulo( ) {


return titulo;
}
public String devolver_autores( ) {
return autores;
}
public int [ ] devolver_fecha( ) {
return fecha_edicion;
}
} // Fin clase publicacin

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

13

2.2.1. Concepto de Herencia (IX)


class Tesis extends Publicacion {
protected String departamento;
public Tesis (String titulo, String autores, String departamento,
int dia, int mes, int agno) {
this.titulo=titulo;
this.autores=autores;
fecha_edicion [0]=dia;
fecha_edicion [1]=mes;
fecha_edicion [2]=agno;
this.departamento=departamento;
}
public String devolver_departamento( ) {
return departamento;
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

14

2.2.1. Concepto de Herencia (X)


main:
class Herencia {
public static void main(String [] args) {
Tesis una_tesis= new Tesis (Sistemas Grid",
Rosala Gmez","Informtica",16,3,2009);
System.out.println("Titulo: " +una_tesis.devolver_titulo( ));
System.out.println("Autor/es: " +una_tesis.devolver_autores( ));
System.out.println("Departamento:
+una_tesis.devolver_departamento( ));
int [ ] fecha = una_tesis.devolver_fecha( );
System.out.println("Fecha: "+fecha[0]+"/"+fecha[1] + "/+ fecha[2]);
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

15

2.2.1. Concepto de Herencia (XI)

El resultado del programa sera,


Titulo: Sistemas Grid
Autor/es: Rosala Gmez
Departamento: Informtica
Fecha: 16/3/2009

Herencia y mtodos constructores


No tiene sentido que un mtodo constructor se herede.
Hay alguna forma de inicializar las variables de la clase padre,
como hace el constructor?
En Java es posible con la referencia super (de superclase) que
obedece a la siguiente sintaxis:
super(lista_de_parmetros);
lista_de_parmetros especifica los parmetros del constructor
de la superclase. Si se utiliza super( ), tiene que ser la primera
sentencia ejecutada dentro del constructor de la subclase.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

16

2.2.1. Concepto de Herencia (XII)

class Tesis extends Publicacion {


Ejemplo de las clases Publicacin y Tesis donde usando la
protected
departamento;
referencia
super(String
):
public
Tesis
(StringPublicacion
titulo, String
class
Tesis
extends
{ autores,
String departamento;
departamento,int dia, int mes, int agno) {
protected String
this.titulo=titulo;
this.autores=autores;
public
Tesis(String titulo, String autores,
fecha_edicion
String[0]=dia;
departamento, int dia, int mes, int agno) {
fecha_edicion [1]=mes;
fecha_edicion
[2]=agno;
super(titulo,autores,dia,mes,agno);
// Uso de super
this.departamento=departamento;
this.departamento=departamento;
}}
public
publicString
Stringdevolver_departamento(
devolver_departamento()){{
returndepartamento;
departamento;
return
}}
}}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

17

2.2.1. Concepto de Herencia (XIII)


Otra cuestin a tener en cuenta es que los miembros (datos y
mtodos) declarados como privados en la clase padre, y que
por lo tanto no se heredan, existen y se usan normalmente si el
objeto de clase hija invoca a un mtodo heredado del padre
que a su vez usa esa/s variable/s o mtodos. Esto implica que
los datos/mtodos de una clase padre pueden ser privados sin
problema. Las clases hijas accedern a ellos a travs de los
mtodos de la clase padre que los use.
Un ejemplo tpico seran los mtodos privados de soporte que
usa un mtodo del padre que se hereda. Cuando el mtodo
heredado se invoque desde el hijo dichos mtodos funcionarn
normalmente. No es necesario declarar como protected los
mtodos de soporte.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

18

2.2.1. Concepto de Herencia (XIV)


Se usan atributos protected en la clase padre y los heredan
las subclases o se usan atributos private que se
consultan/modifican en las subclases a travs de los mtodo
de actualizacin y consulta heredados de la clase padre?
Nosotros vamos a usarlos normalmente como protegidos, pero
esto tiene sus inconvenientes por lo que algunos autores
aconsejan usar atributos privados siempre:
Si los atributos de una superclase son privados no se
puede acceder a ellos ni desde sus subclases lo que
permite mantener la encapsulacin de los objetos. Si los
atributos son protegidos s se puede acceder a ellos
desde las subclases. Esto hace que se creen jerarquas
de clases fuertemente acopladas (y ya hemos hablado de
que el acoplamiento entre clases no es conveniente)
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

19

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (I)

Supongamos que en una clase hija declaramos una variable o


definimos un mtodo con el mismo nombre o firma que una
variable o mtodo heredadas qu pasa?
a) Variables
Cuando una variable se hereda y en la clase hija
declaramos una nueva variable con el mismo identificador,
la nueva variable es la que se usa. Se dice que hemos
enmascarado la variable original
La variable de la clase padre sigue existiendo, y se podra
acceder a ella pero indicando explcitamente que nos
referimos a la clase padre con el prefijo super.
Ejemplo:

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

20

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (II)
class Padre{
protected int dato=10;
} // Fin clase Padre

class Hija extends Padre {


private int dato;
2 Enmascaramiento
public Hija (int dato) {
3
this.dato =dato;
}
public void imprime_hija() {
System.out.println("Valor de dato en Hija: "+dato);
}
public void imprime_padre() {
System.out.println("Valor de dato en Padre: "
+super.dato);
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

21

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (III)
class Herencia {
public static void main(String [] args) {
Hija ejemplo = new Hija(5);
ejemplo.imprime_hija( );
ejemplo.imprime_padre( );
}
}

El resultado del programa sera,


Valor de dato en Hija: 5
Valor de dato en Padre: 10

Como se puede comprobar en el programa el enmascaramiento de


variables suele producir cdigo confuso, por lo que se
recomienda evitar su uso.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

22

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (IV)
b) Mtodos
Un comportamiento similar ocurre cuando definimos un
mtodo con la misma firma (nombre y parmetros) y tipo de
retorno que otro que se hereda.
En este caso, el mtodo al que se accede a travs de los
objetos de la clase hija es al definido en la clase hija.
Se dice que el nuevo mtodo sobrescribe el mtodo
heredado. Es importante distinguir la sobrescritura de la
sobrecarga:
Sobrecarga: El mismo identificador pero distinta firma
(diferentes parmetros).
Sobrescritura: La misma firma y tipo de retorno que un
mtodo heredado.
El cdigo de cada mtodo sobrescrito es diferente en la
clase hija que en la clase padre. As, se consigue
particularizar el comportamiento de la clase. El sistema
sabe qu versin del mtodo debe usar
Ejemplo:
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

23

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (V)
class ClaseX {
protected int n=25;
public void imprimir( ){
System.out.println("En ClaseX, n= "+n);
}
}
class ClaseY extends ClaseX {
protected int m=10;
public void imprimir( ){
System.out.println("En ClaseY, m= "+m);
}
}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

Sobrescritura
del mtodo
heredado

24

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (VI)

Main:
class Herencia {
public static void main(String [ ] args) {
ClaseX x = new ClaseX( );
ClaseY y = new ClaseY( );
x.imprimir( );
y.imprimir( );
}
}

El resultado es:
En ClaseX, n= 25
En ClaseY, m= 10

La gran ventaja de la sobrescritura es que podemos especificar


versiones personalizadas de un mtodo para las clases hijas.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

25

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (VII)

Cmo funciona la sobrescritura?Cmo sabe el sistema qu


cdigo (clase padre o clase hija) debe activar?:
Enlazamiento esttico y dinmico
Esttico: es el soportado por los lenguajes no orientados a objetos.
El compilador genera una llamada a un nombre especfico de
mtodo y el enlazador (linker) resuelve la llamada a la direccin
absoluta del cdigo que se ha de ejecutar.
Dinmico: cuando hay sobrescritura de mtodos el compilador se
asegura de que el mtodo existe y realiza la verificacin de tipos de
los argumentos y del valor de retorno. El compilador no conoce cul
es el mtodo a ejecutar en tiempo de compilacin. Ejemplo: una
clase padre donde se define un mtodo para que lo herede una
clase hija. Ese mtodo (mtodo A) usa otro mtodo distinto (mtodo
B) que se sobrescribe en la clase hija. Qu pasa al crear un objeto
de la clase hija? Tendremos el cdigo heredado del primer mtodo
(mtodo A) el cual usa una invocacin al cdigo sobrescrito del
mtodo B en el objeto. Sin embargo, la clase padre se puede
compilar independientemente de la clase hija, as que el mtodo A
no puede saber en tiempo de compilacin qu versin del mtodo
B se va a usar.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

26

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (VIII)
En un diagrama, en tiempo de compilacin la situacin es sta:
Mtodo_B
(Clase padre)
Mtodo_A

?
Mtodo_B
(Clase hija)

Con qu Mtodo_B enlazaramos al Mtodo_A?. En funcin de la


ejecucin del programa podemos necesitar una versin u otra. La
sobrescritura implica determinar cul es la versin a usar del mtodo
sobrescrito en tiempo de ejecucin.
Lo que hace el sistema es incluir algo ms de cdigo para que en
tiempo de ejecucin se pregunte a qu clase pertenece el mtodo
invocado y activar la versin correcta de dicho mtodo. Esta forma
de enlazamiento se denomina dinmico (dynamic binding):
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

27

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (IX)

Ejemplo. Supongamos que la variable i se lee por teclado:


if (i==1){
Clase_Padre objeto = new Clase_Padre( );
}
else {
Clase_Hija objeto = new Clase_Hija( );
}
objeto.mtodo_B( );

Hasta que no se ejecute el cdigo no se sabe qu mtodo B hay


que ejecutar

El enlazamiento dinmico hara lo siguiente:

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

28

2.2.2. Enmascaramiento de variables y


sobrescritura de mtodos (X)
Enlazamiento dinmico:

Clase padre

Mtodo_B
(Clase padre)

Mtodo_A

Clase hija

Mtodo_B
(Clase hija)

Por defecto, los mtodos en Java usan enlazamiento dinmico lo


que implica una disminucin (pequea) de rendimiento. Si queremos
optimizar en velocidad un mtodo que sabemos que no va a ser
sobrescrito, lo debemos declarar con modificador final para forzar
enlazamiento esttico. Un mtodo final no puede ser sobreescrito
en la clase hija. Una clase final no puede ser heredada.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

29

2.2.3. Jerarquas de Clases (I)


Es posible crear complejas relaciones jerrquicas usando herencia:
Padre

Hijo 1

Nieto 1

Primer nivel jerrquico

Hijo 2

Nieto 2

Hijo 3

Nieto 3

Segundo nivel
jerrquico

Tercer nivel jerrquico

El mecanismo de herencia es transitivo, esto es, los atributos o


procedimientos pasan de la clase padre a las clases hijas y de stas a
su vez pasan a sus descendientes (incluyendo en este caso los
nuevos atributos y procedimientos declarados en la clase hija).

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

30

2.2.3. Jerarquas de Clases (II)

Respecto a la relacin de herencia podemos establecer la


denominada herencia del invariante. Las caractersticas
(propiedades) que distinguen una clase descendiente de una
ascendiente se denominan invariantes de la clase. En una relacin
de herencia, una subclase admite como caracterstica suya la
unin por un y lgico de lo que la distingue a ella y a todas sus
antecesoras. Es decir, a una subclase le corresponden todos los
invariantes de su lnea jerrquica unidos por un y lgico.

Ejemplo:

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

31

2.2.3. Jerarquas de Clases (III)


Figura_cerrada

es cerrado
y tiene

Polgono

lados rectos
y tiene

Tringulo

tres lados
y tiene

Tringulo_equilatero

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

tres lados iguales


32

2.2.3. Jerarquas de Clases (IV)

En Java, todas las clases heredan de la clase Object. Esta clase


constituye el nodo raz de toda la jerarqua de clases de Java.
Cuando hacemos:
class nombre_clase {
}

Estamos implcitamente haciendo


class nombre_clase extends Object {
}

El caso en el que una clase hereda de otra no es bice para que


tambin implcitamente se herede de Object. Esta situacin no se
considera herencia mltiple.

La clase Object posee mtodos interesantes que heredan todos


sus descendientes, como el mtodo toString( ). Este mtodo
devuelve una cadena conteniendo una descripcin del objeto que
lo llama. Cualquier clase puede sobrescribir este mtodo.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

33

2.2.3. Jerarquas de Clases (V)

Ejemplo:
class Alumno{
private String nombre;
private int matricula;
// Constructor
Alumno(String nombreAlumno, int matriculaAlumno){
nombre = nombreAlumno;
matricula = matriculaAlumno;
}
// Sobrescritura del mtodo toString
public String toString( ) {
return "Los datos del alumno son:" + nombre + " "
+ matricula;
}
}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

34

2.2.3. Jerarquas de Clases (VI)


Main:
class Facultad{
public static void main(String args[ ]){
Alumno alumno1 = new Alumno("Juan",123);
System.out.println(alumno1);
Alumno alumno2 = new Alumno("Maria",124);
System.out.print(alumno2);
}
}

Se puede
invocar el
toString()
usando slo
el
identificador
del objeto

La salida del programa sera,


Los datos del alumno son: Juan 123
Los datos del alumno son: Maria 124
Podramos haber usado
System.out.println(alumno1.toString())
System.out.print(alumno2.toString())
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

35

2.2.3. Jerarquas de Clases (VII)


Importante!
No usar el mtodo toString como sustituto de los
mtodos de consulta
El mtodo toString devuelve una cadena que puede estar
compuesta por los valores de los atributos, pero no sirve
para consultar dichos valores
Toda clase debe tener mtodos para consulta de sus
atributos
Otro mtodo de la clase Object que puede ser de utilidad es el
mtodo equals( ) que sirve para comparar si dos objetos
separados son del mismo tipo y contienen los mismos datos
(tienen el mismo valor de sus atributos). El mtodo devuelve true
si los objetos son iguales y false en caso contrario. El mtodo se
puede sobrescribir para adaptarlo a nuestro programa.
Esta comparacin no es la misma que proporciona el operador
==, que solamente compara si dos referencias a objetos
apuntan al mismo objeto.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

36

2.2.4. Organizacin de Jerarquas de


Clases (I)

En Java tenemos un mecanismo para agrupar diferentes


jerarquas de clases y referirlas con un nico identificador, se trata
de los paquetes.

Un paquete es una coleccin de clases agrupadas juntas bajo un


solo nombre. Las clases en un paquete no tienen porqu estar
relacionadas por herencia.

Los paquetes seran equivalentes a las bibliotecas de funciones


de otros lenguajes.

Para poder trabajar con paquetes tenemos que hacer dos cosas:
a) Crearlos, indicando qu clases forman parte del mismo y
dnde se va a encontrar dicho paquete.
b) Usarlo, importando el paquete tal y como ya hemos visto en
programas anteriores.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

37

2.2.4. Organizacin de Jerarquas de


Clases (II)
a) Creacin de paquetes
- Para crear un paquete, el programador debe hacer dos cosas:
1. Identificar los ficheros y clases que pertenecern al
paquete.
2. Colocar todas las versiones compiladas de las clases (los
ficheros .class) en un subdirectorio con el mismo nombre
del paquete.
- Especificacin de pertenencia a un paquete:
package nombre_ paquete;
class nombre_clase1 {
...
}
class nombre_clase2 {
...
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

Primera
sentencia del
fichero

38

2.2.4. Organizacin de Jerarquas de


Clases (III)

El emplazamiento del directorio donde se encuentran los paquetes


se identifica normalmente en la variable de entorno CLASSPATH.

b) Uso de paquetes
- Para usar un paquete hay que importarlo:
import nombre_paquete.nombre_clase;
import nombre_paquete.*;
- Tambin se puede usar sin importar, pero hay que indicar el
nombre del paquete precediendo a la clase de la forma siguiente:
nombre_paquete.nombre_clase

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

39

2.2.5. Polimorfismo (I)


Polimorfismo indica en orientacin a objetos que una misma
identificacin puede referir a distintas entidades.
Se trata de una de las caractersticas definitorias de la
orientacin a objetos.
El polimorfismo es la capacidad de una entidad determinada
(entindase referencia) de conectarse a objetos de varias
clases relacionadas por herencia.
Esta capacidad se puede usar si esos distintos objetos de
diferentes clases tienen mtodos sobrescritos, que son los que
se van a invocar a travs de la referencia polimrfica.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

40

2.2.5. Polimorfismo (II)


Cmo se usa el polimorfismo:
Tpicamente, en una clase padre se declara un mtodo que
es el que se va usar polimrficamente.
Ese mismo mtodo se sobrescribe en clases que son
derivadas de la clase padre. As, existirn mtodos en las
clases descendientes con la misma firma que el de la clase
padre.
Si un objeto de la clase padre se declara en un programa, la
definicin del mtodo original que se encuentra en la clase
padre ser la que se invoque cuando se llame al mtodo.
Sin embargo, si un objeto de una clase hija se asigna
posteriormente a la referencia de la clase padre, entonces
se invoca la definicin de mtodo para la clase hija.
Cuando tenemos un mtodo polimrfico necesariamente se
usa el enlazamiento dinmico y el sistema comprueba la
clase real del objeto antes de invocar la definicin de
mtodo apropiada.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

41

2.2.5. Polimorfismo (III)


En trminos ms prcticos, el polimorfismo implica que una
referencia puede referir a cualquier objeto de su clase o a un
objeto de una clase descendiente de la primera.
Ejemplo:

Vacaciones

Navidades

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

Verano

42

2.2.5. Polimorfismo (IV)


Podramos hacer:
Referencia de clase padre
Vacaciones mis_vacaciones;
mis_vacaciones = new Navidades( );
Objeto de clase
hija

Suponiendo que exista un mtodo sobrescrito llamado


duracion( ) que nos de el nmero de das festivos, la referencia
mis_vacaciones (que es de clase Vacaciones) se podra usar
para invocar el mtodo duracion( ) en el objeto mis_vacaciones,
que es de clase Navidades.
Esto es importante:
Es la clase del objeto referido la que indica qu mtodo
usar, no la clase con la que se declara inicialmente la
referencia.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

43

2.2.5. Polimorfismo (V)


Programa de ejemplo:
class Padre{
public void dondeEstoy( ) {
System.out.println("Estoy en el metodo del Padre");
}
}
class HijaPrimera extends Padre{
public void dondeEstoy( ) {
System.out.println("Estoy en el metodo de la HijaPrimera");
}
}
class HijaSegunda extends Padre{
public void dondeEstoy( ) {
System.out.println("Estoy en el metodo de la HijaSegunda");
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

44

2.2.5. Polimorfismo (VI)


class Herencia {
public static void main(String [ ] args) {
Padre padre =new Padre();
HijaPrimera hijaPrimera =new HijaPrimera();
HijaSegunda hijaSegunda =new HijaSegunda();
Padre polimorfico;
polimorfico=padre; // hace referencia a un objeto padre
polimorfico.dondeEstoy();
polimorfico=hijaPrimera; //hace referencia a un objeto
//hijaPrimera
polimorfico.dondeEstoy();
polimorfico=hijaSegunda; //hace referencia a un objeto
//hijasegunda
polimorfico.dondeEstoy();
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

45

2.2.5. Polimorfismo (VII)


La salida es:
Estoy en el metodo del Padre
Estoy en el metodo llamada de la HijaPrimera
Estoy en el metodo llamada de la HijaSegunda

Para entender la utilidad del polimorfismo imaginemos un


mtodo que acepta como parmetro una referencia polimrfica.
Dentro del mtodo se usar la referencia de forma normal,
invocando los mtodos sobrescritos. Fijmonos en que el
mtodo slo acepta la referencia, pero l no realiza la
asignacin de la referencia a un objeto de una clase o de otra.
Por lo tanto, el mtodo es el mismo, independientemente de la
clase a la que pertenezca el objeto referido por la referencia.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

46

2.2.5. Polimorfismo (VIII)


Otro ejemplo tpico es el de una estructura de datos de
referencias polimrficas. Por ejemplo, imaginemos que
necesitamos una lista, implementada como una matriz
monodimensional de objetos de clase Navidades y otra de
objetos de clase Verano. Sin polimorfismo no hay ms solucin
que usar dos matrices. Sin embargo, con el polimorfismo
podramos usar una sola matriz de referencias de clase
Vacaciones. El polimorfismo nos permite ir vinculando cada
elemento de esta matriz a objetos de clase Navidades o Verano,
segn convenga. Es decir, slo hace falta una estructura de
datos.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

47

2.2.5. Polimorfismo (IX)


Con una referencia polimrfica no se pueden invocar mtodos
que sean exclusivamente de la clase hija, aunque en ese
momento la referencia se refiera a un objeto de la clase hija,
slo se pueden invocar mtodos heredados de la clase padre.
Si se quiere invocar un mtodo de la clase hija con una
referencia polimrfica que en ese instante se refiera a un
objeto de clase hija se puede usar un molde.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

48

2.2.5. Polimorfismo (X)


Ejemplo:
Sean dos clases relacionadas por herencia
Figura y Triangulo
Figura tiene un mtodo imprimir que sobrescribe Triangulo.
Triangulo adems tiene un mtodo llamado calcular_area.
Si hacemos:
Figura f;
Triangulo t;
f=t;
f.imprimir(); invocara al mtodo imprimir de Triangulo.
f.calcular_area(); dara error.
Sin embargo,
(Triangulo) f.calcular_area(); //USO de un MOLDE
invocara al mtodo calcular_area de la clase Triangulo
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

49

2.3. Mecanismos adicionales de abstracin


basados en herencia
En este punto consideraremos dos mecanismos de
abstraccin a usar en conjuncin con la herencia. En primer
lugar consideraremos las clases abstractas y su relacin con
las subclases. En segundo lugar introduciremos las interfaces,
que nos permiten definir la especificacin de un conjunto de
mtodos. Comencemos con las clases abstractas.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

50

2.3.1. Clases y mtodos abstractos (I)

En programacin orientada a objetos no es necesario que todos los


mtodos de una clase estn implementados.
Puede ser conveniente disponer de clases en las que todos los
procedimientos estn recogidos pero no todos estn implementados.
Estas clases no totalmente implementadas se denominan clases
diferidas o abstractas. Su uso, lgicamente, es a travs de la herencia
ya que no tiene sentido pretender crear objetos de una clase no
totalmente implementada.
Los mtodos no implementados, aunque especificados (es decir,
indicando su firma y tipo de retorno), se denominan mtodos
abstractos y lgicamente (aunque no necesariamente) una clase
abstracta debe contener al menos un mtodo abstracto.
Las clases abstractas se usan dentro de una jerarqua de clases en la
cual la clase abstracta define slo parte de su implementacin,
difiriendo el resto a las clases hijas por medio de la sobrescritura de
los mtodos abstractos.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

51

2.3.1. Clases y mtodos abstractos (II)

Para declarar una clase como abstracta en Java se usa el modificador


abstract. El mismo modificador se aplica para identificar un mtodo
abstracto. La sintaxis para declarar una clase abstracta, por lo tanto, es:
abstract class nombre_clase {
// cdigo de la clase
}

Anlogamente, para definir un mtodo abstracto dentro de una clase


abstracta la sintaxis sera:
abstract visibilidad tipo_retorno nombre_mtodo(lista_parmetros);

En un mtodo abstracto no se indica su implementacin, pero s qu


parmetros acepta y qu devuelve. Un mtodo abstracto no puede ser
declarado como final (pues se debe poder sobrescribir) ni static (pues no
puede ser invocado ya que no tiene implementacin). Tampoco se pueden
declarar constructores abstractos.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

52

2.3.1. Clases y mtodos abstractos (III)


En notacin UML indicamos una clase abstracta especificando su
nombre en cursiva. Si esto es complicado de representar (en una pizarra
por ejemplo) se puede incluir un valor etiquetado (entre llaves, { }) al lado
de la clase para indicar que es abstracta. Tambin se podra usar un
estereotipo (extensin semntica de UML), que se indica entre los
smbolos << >>:

<<abstracta>>
Clase {abstracta}

Clase

Atributos

Atributos

Procedimientos

Procedimientos

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

53

2.3.1. Clases y mtodos abstractos (IV)

La utilidad prctica de las clases abstractas radica en el hecho de no


poderse crear objetos de dicha clase. As, la clase abstracta especifica
una abstraccin. Las clases hijas heredan la estructura de mtodos de
las clases padre y para poder crear objetos de las clases hijas stas
deben sobrescribir todos los mtodos abstractos que han heredado.
Al usar un mtodo abstracto en la clase padre, forzamos a que
explcitamente todas las clases hijas que lo hereden tengan que elegir
como implementarlo. Si no se usan mtodos abstractos, las clases
hijas no estn forzadas a hacer la eleccin. Pueden usar el mtodo
heredado de su clase padre.

Las clases abstractas se pueden usar para declarar referencias a


objetos, al igual las clases no abstractas. De hecho una clase
abstracta se puede usar de la misma forma que cualquier otra clase,
excepto que no se pueden crear objetos de ella. Esta forma de trabajar
es habitual, se declara una referencia de la clase abstracta (la clase
padre de una jerarqua) para referir a objetos de clases hijas (no
abstractas) por medio de referencias polimrficas.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

54

2.3.1. Clases y mtodos abstractos (V)


Veamos un ejemplo. Sea,

Automvil

{abstracta}

Deportivo

Turismo

Familiar

Podemos construir el siguiente programa:


Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

55

2.3.1. Clases y mtodos abstractos (VI)


abstract class Automovil {
abstract public void eslogan( );
}
class Deportivo extends Automovil {
public void eslogan() {
System.out.println("Veloz como el rayo");
}
}
class Turismo extends Automovil {
public void eslogan() {
System.out.println("Para el uso diario");
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

56

2.3.1. Clases y mtodos abstractos (VII)


class Familiar extends Automovil {
public void eslogan() {
System.out.println("Cabe hasta el gato");
}
}

El mtodo main podra ser:

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

57

2.3.1. Clases y mtodos abstractos (VIII)


// Clase que contiene el mtodo main
class Herencia {
public static void main(String [ ] args) {
Matriz de
referencias
Automovil [ ] auto=new Automovil [3];
polimrficas
auto [0]=new Deportivo();
auto [1]=new Turismo();
Objetos de
clases diferentes
auto [2]=new Familiar();
imprime_eslogan(auto);
}
public static void imprime_eslogan(Automovil [ ] auto) {
for (int i=0; i<=2; i++)
auto[i].eslogan();
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

58

2.3.1. Clases y mtodos abstractos (IX)


El resultado del programa sera:
Veloz como el rayo
Para el uso diario
Cabe hasta el gato

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

59

2.3.2. Interfaces (I)


Una interfaz es una coleccin de constantes y mtodos
abstractos. No son clases, pero pueden usarse en la definicin
de una clase. La sintaxis general en Java es:
interface nombre_interfaz {
declaracin de constantes
declaracin de mtodos abstractos
}
En la declaracin de los mtodos se debe incluir el tipo de
retorno y la lista de parmetros. Adems, slo est permitido
el uso de los modificadores public y abstract. Sin embargo no
son necesarios, porque por defecto los mtodos de una
interfaz son pblicos y abstractos. Las constantes en una
interfaz son siempre public, static y final.
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

60

2.3.2. Interfaces (II)

Las interfaces no se usan por s mismas sino que se implementan


(una especie de herencia) en una clase. La clase proporcionar las
implementaciones para cada uno de los mtodos definidos en la
declaracin de la interfaz.

En Java se usa la palabra clave implements para indicar que una


clase implementa una interfaz. La sintaxis es:
class nombre_clase implements nombre_interfaz {
implementacin de los mtodos de la interfaz
}

Si una clase incluye una o varias interfaces pero no implementa


todos lo mtodos definidos por la/s interface/s la clase debe
declararse como abstract.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

61

2.3.2. Interfaces (III)

Herencia entre interfaces:


Se pueden aadir nuevas declaraciones de mtodos o constantes
a una interfaz haciendo uso de la herencia y tambin se pueden
combinar varias interfaces en una nueva interfaz gracias a la
herencia.
Ejemplo:
interface A {
void metodo A();
}
interface B extends A{
void metodo B();
}
interface C extends B {
void metodo C();
}
C ser una nueva interfaz que contendr los mtodos de A, B y C

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

62

2.3.2. Interfaces (IV)

Notacin UML: una interfaz se puede representar de dos formas:


Se representa igual que una clase, colocando en el rectngulo la
palabra <<interface>>. Al igual que en la clase se indican
atributos (constantes), mtodos (abstractos) y visibilidad
Tambin se puede representar con un crculo unido por una lnea
a una clase con las operaciones de la interfaz al lado del crculo.
Una clase que usa la interfaz se une por medio de una flecha de
lnea discontinua a los crculos o al rectngulo de la interfaz

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

63

2.3.2. Interfaces (V)


<<interface>>
Nombre
+atributo:tipo=valor
+metodo([parmetro:tipo, ....]):tipo

En UML:
- los atributos y
mtodos estticos van
subrayados.
- los mtodos
abstractos se
representan en cursiva

Nombre_Clase

<<interface>>
Nombre
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

64

2.3.2. Interfaces (VI)

Con respecto a las constantes definidas en la interfaz, stas se


comportan como si estuvieran definidas en la clase que implementa
dicha interfaz. Esto nos proporciona una forma de poder distribuir
constantes entre varias clases. Para ello basta con definir las
constantes en una interfaz y luego hacer que las diferentes clases
implementen dicha interfaz.

Por lo que respecta al paso de parmetros y las interfaces, hay que


decir que un parmetro formal declarado de tipo interfaz puede
aceptar como parmetro actual cualquier clase o subclase que
implemente dicha interfaz.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

65

2.3.2. Interfaces (VII)

Diferencias entre interfaces y clases abstractas:


Una, la simplicidad en la notacin. En una interfaz todos los
mtodos son abstractos por lo que se puede omitir la palabra
clave abstract. A su vez, todas las constantes son public, static y
final, por lo que se pueden omitir las palabras clave.
La otra razn, ms importante, es que una clase puede
implementar ms de una interfaz, mientras que una subclase slo
se puede derivar de una clase. Por lo tanto, en cierto sentido, las
interfaces en Java nos permiten cierta capacidad de herencia
mltiple. La sintaxis para la implementacin de varias interfaces
sera:
class nombre_clase implements interfaz_1,..., interfaz_n {
--- cuerpo de la clase --}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

66

2.3.2. Interfaces (VIII)


Es posible usar interfaces (implements) y herencia (extends) a
la vez
Cules son las similitudes entre interfaces y clases
abstractas?
Por un lado, que tanto interfaces como clases abstractas
definen mtodos abstractos que sern sobrescritos
posteriormente en clases particulares.
Por otro lado, que ambas se pueden usar como nombres
de tipos genricos para referencias. Ambas se pueden usar
como parmetros formales.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

67

2.3.2. Interfaces (IX)


En la API de Java hay muchas interfaces definidas de las que
derivan muchas de las clases predefinidas de JAVA.
Una de esas interfaces es la interfaz Iterator definida en el
paquete java.util como Interface Iterator <E> (es genrica)
La interfaz Iterator permite avanzar por los objetos que
contiene una coleccin, siendo una coleccin un grupo de
objetos como una lista, un conjunto, una cola o una pila. Una
coleccin sera una estructura de datos.
Mtodos de la interfaz:
hasNext(): Devuelve true si la coleccin tiene ms elementos
next():Devuelve el siguiente elemento de la coleccin
remove(): Elimina de la coleccin el ltimo elemento devuelto
por el iterador.

La clase Scanner implementa esta interfaz y contiene mtodos


para leer de un fichero similares a estos (vistos en Fun. Prog I)

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

68

2.4. Genricos (I)

Como ya se ha comentado, en Java podemos tener las denominadas


colecciones de objetos (grupo de objetos como una lista, un conjunto,
una cola o una pila). Antes de Java 5 cuando introducamos objetos en
una coleccin estos se guardaban como objetos de tipo Object,
aprovechando el polimorfismo para poder introducir cualquier tipo de
objeto en la coleccin. Esto nos obligaba a hacer un casting al tipo
original al obtener los elementos de la coleccin.

Esta forma de trabajar no solo implica tener que escribir ms cdigo,


sino que es propenso a errores porque carecemos de un sistema de
comprobacin de tipos. Si introdujramos un objeto de tipo incorrecto
el programa compilara pero lanzara una excepcin en tiempo de
ejecucin.

Desde Java 5 se cuenta con los tipos genricos, que permiten aplicar
abstraccin de tipos de datos de forma parecida (no igual) a los
templates o plantillas de C++. En Java, esto se aplica a los tipos
referencia (en la prctica a las clases, no a los tipos primitivos).

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

69

2.4. Genricos (II)

Los tipos genricos o tipos parametrizados permiten definir una clase o


interfaz una sola vez y despus crear objetos de ella de diferentes
tipos. Esto es, un tipo puede usarse como parmetro en la definicin de
un mtodo o de una clase. Una clase podr trabajar con diferentes tipos
de datos.
A estas clases a las que podemos pasar un tipo como parmetro se
les llama clases parametrizadas, clases genricas, definiciones
genricas o simplemente genricos (generics).
Para crear una clase parametrizada solo hay que aadir el tipo
parametrizado despus del nombre de la clase. El tipo se indica
colocando un identificador para el mismo entre < y > despus del
nombre de la clase. Se usa un identificador cualquiera, lo tpico es T:
<T> o E <E> como en la API de Java. Se pueden especificar uno o
varios tipos:
- Un tipo: <T>
- Dos tipos: <T, V>

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

70

2.4. Genricos (III)

Ejemplo con un tipo:


class Ejemplo <T> {
T elemento; //Se declara un objeto de tipo T
public Ejemplo (T elemento_ini){
elemento=elemento_ini;
}
public T get_elemento(){
return elemento;
}

//T tipo de retorno

}
T representa el tipo genrico y se puede usar como un tipo normal.
Recordemos que T representa un tipo referencia, no un tipo primitivo.
Si se quieren usar tipos primitivos se debe hacer a travs de las clases
contenedoras de Java

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

71

2.4. Genricos (IV)

En el ejemplo anterior, cuando el objeto se cree, T se remplazar por el


tipo real.

Para usar una clase parametrizada basta con indicar el tipo concreto al
crear objetos:
Ejemplo<String> miEjemplo =
new Ejemplo<String>(No hay mal que por bien no venga);

En el ejemplo anterior usbamos la clase String. Si quisiramos usar la


clase contenedora Integer haramos:
Ejemplo<Integer> miEjemplo = new Ejemplo<Integer>(33);

La invocacin al mtodo get_elemento() devolver un entero o una


cadena dependiendo del tipo que hayamos definido el objeto (String o
Integer)

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

72

2.4. Genricos (V)


String cad=miElemplo.get_elemento() //miEjemplo es <String>
int x= miEjemplo.get_elemento(); //miEjemplo es <Integer>

La lnea anterior se podra escribir como:


int x= miEjemplo.get_elemento().intValue();
para transformar el objeto de tipo Integer que devuelve el mtodo a un
tipo primitivo int. Debido al auto-boxing-auto-unboxing de Java no
hace falta, automticamente hace la conversin de Integer a int o de int
a Integer (lo mismo ocurre con los dems tipos primitivos numricos)

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

73

2.4. Genricos (VI)


Representacin en UML de una clase genrica

Clase Ejemplo

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

74

2.4. Genricos (VII)


Ejemplo:
class Ejemplo <T> {
private T elemento;
//Se declara un objeto de tipo T
public Ejemplo (T elemento_ini){
elemento=elemento_ini;
}
public T get_elemento(){
//T tipo de retorno
return elemento;
}
public void set_elemento(T ele){
elemento=ele;
}
public String toString(){
return "valor= "+elemento;
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

75

2.4. Genricos (VIII)


class Principal {
public static void main (String [] args) {
Ejemplo <String> strEjemplo;
strEjemplo=new Ejemplo("No hay mal que por bien no venga");
String cadena=strEjemplo.get_elemento();
System.out.println("cadena= "+cadena);
Ejemplo <Integer> inEjemplo;
inEjemplo=new Ejemplo <Integer> (33);
int entero=inEjemplo.get_elemento();
System.out.println("entero= "+entero);
inEjemplo.set_elemento(50);
System.out.println(inEjemplo.toString());
}
}
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

76

2.4. Genricos (IX)

Las clases genricas son tiles cuando se trabaja a mayor nivel de


abstraccin, por ejemplo con clases que usen otras clases. Un caso
sera el del TAD lista. Podemos hacer listas de objetos y el
comportamiento de la lista sera siempre el mismo: aadir elementos,
eliminar elementos, Para tener una sola clase lista programaramos
esta como genrica y as podra admitir como elementos objetos de
cualquier clase:
Lista<ClaseA> miLista = new Lista<ClaseA>( );
Lista<ClaseB> miOtraLista = new Lista<ClaseB>( );
ClaseA a=new ClaseA( );
ClaseB b=new ClaseB( );
miLista.incluye(a);
miOtraLista.incluye(b);

La clase Lista se maneja igual independientemente del tipo de objetos


que est usando.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

77

2.4. Genricos(X)

Es posible crear un mtodo o un constructor genrico en una clase que


no sea genrica. Si esto es as habr que indicar que el mtodo es
genrico en la cabecera del mtodo.
<T,V,> tipo_retorno nombre_metodo (lista de parmetros){}
Ejemplo: public <T> boolean comprobar (T a){}

En el ejemplo se est pasando como parmetro al mtodo un tipo


genrico. Con <T> se indica que el mtodo va a usar un tipo genrico, T
en su ejecucin. boolean indica el tipo de retorno del mtodo.

Tambin es posible tener interfaces genricas. Se especifican de


manera similar a las clases genricas.
interface nombre_interfaz <T,V>{}
class nombre_clase <T,V> implements nombre_intefaz <T,V,..>{}

Las clases genricas pueden formar parte de una jerarqua de clases,


siendo superclases o subclases

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

78

2.4. Genricos(XI)
Restricciones:
o No se pueden crear objetos de clases genricas, slo referencias.
T objeto; //OK
objeto=new T (); //Mal
o No se pueden crear matrices de genricos, slo referencias
T matriz [ ]; //OK
matriz =new T [10]; //Mal
o No se pueden crear matrices de referencias genricas de un tipo
especfico
Nombre_clase <Integer> matriz []= new Nombre_clase<Integer>[10] //Mal
Nombre_clase <?> matriz []= new Nombre_clase<?>[10] //OK
? es un argumento wildcard (carcter comodn) que representa un
tipo desconocido.

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

79

2.4. Genricos(XII)
class Ejemplo_Metodo_Generico {
/*
* Mtodo genrico que imprime una matriz
* El mtodo imprime_matriz se podra sobrecargar
* (sera equivalente) pero ms tedioso
*
*/
public static <T> void imprime_matriz(T[] a) {
for ( int i=0; i<a.length;i++ ){
System.out.printf("%s ",a[i]); //a[i] equivale a
//a[i].toString()

}
System.out.println();
}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

80

2.4. Genricos(XIII)
public static void main(String args[]){
/* Creacin de 4 matrices:
de enteros, de dobles, de caracteres y de Cuentas */
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
Cuenta [] c=new Cuenta [2];
c[0]=new Cuenta (1,1.0);
c[1]=new Cuenta (2,2.0);
System.out.println( "La matriz de enteros contiene:" );
imprime_matriz( intArray ); // Se pasa una matriz de enteros
System.out.println( "La matriz de dobles contiene:" );
imprime_matriz( doubleArray ); // Se pasa una matriz de dobles

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

81

2.4. Genricos(XIV)
System.out.println( "La matriz de caracteres contiene:" );
imprime_matriz( charArray ); // Se pasa una matriz de caracteres
System.out.println( "La matriz de Cuenta contiene:" );
imprime_matriz( c ); // Se pasa una matriz de caracteres
}
}

Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

82

2.4. Genricos(XV)
class Cuenta{
protected int ncuenta;
protected double saldo;
public Cuenta (int ncuenta, double saldo){
this.ncuenta=ncuenta;
this.saldo=saldo;
}
public int getcuenta() {
return ncuenta;
}
public double getsaldo() {
return saldo;
}
public String toString() {
return "Numero de cuenta "+ncuenta+ " con saldo de "+ saldo+"\n";
}
}//fin clase Cuenta
Fundamentos de Programacin II
C.Muoz Caro & A. Nio-Universidad de Castilla-La Mancha

83

Potrebbero piacerti anche