1 Genéricos en Java Jaime Ramírez, Ángel Lucas GonzálezDLSIIS. Facultad de Informática Universidad Politécnica de Madrid.
2 Introducción Java permite definir clases con variables o parámetros que representan tipos => Clases genéricas Esto es posible, cuando el tipo de un dato no afecta al tratamiento que se le va a dar a ese dato. Un mecanismo similar está disponible en lenguajes como C#, C++ o Ada.
3 Introducción Aparecen en la versión 1.5.Antes se utilizaba la clase Object como “comodín” para simular los genéricos, pero esto conllevaba: Se podían mezclar objetos de las clases más dispares en una misma estructura contenedora de objects. Había que realizar muy a menudo castings (conversión de Object a cualquier otra clase).
4 Motivación Supongamos que en un programa necesitamos una clase ParEnteros: public class ParEnteros { private int a, b; public ParEnteros(int a, int b){ this.a = a; this.b = b; } public ParEnteros swap (){ return new ParEnteros(b, a);
5 Motivación Pero también necesitamos un clase ParCaracteres con los mismos métodos que la anterior. La implementación de los métodos es la misma, porque no depende del tipo del dato manipulado => abstraemos el tipo convirtiéndolo en un parámetro genérico T.
6 Ejemplo clase genérica Parpublic class Par
7 Ejemplo clase genérica Parpublic class Prueba { public static void main(String[] args) { // Instanciación de la clase genérica para Integer // No se puede usar int porque no es una clase Par
8 Restringiendo el parámetro genéricoSupongamos que deseamos añadir a la clase Par un método max(): public T max(){ return ((a>b) ? a : b); } Si añadimos este método sin más, obtendremos un error de compilación, ya que a y b no tienen por qué ser de un tipo comparable con >.
9 Restringiendo el parámetro genéricoDebemos decirle al compilador que el tipo T sólo representará tipos de valores comparables con el > o una función equivalente (compareTo). public class Par
10 Restringiendo el parámetro genéricoEn general, se puede declarar un parámetro genérico de forma que al instanciar la clase se debe proporcionar una clase A que sea subclase de otra B o implemente una cierta interfaz B: class ClaseGen
11 Restringiendo el parámetro genéricoclass Stats< T extends Number > { private T[] nums; Stats(T[] o) { nums = o; } double average() { double sum = 0.0; for(int i=0; i < nums.length; i++) sum += nums[i].doubleValue(); return sum / nums.length; } }
12 Restringiendo el parámetro genéricodouble w = dob.average(); System.out.println("dob average is " + w); // Esto no compila porque String no es // subclase de Number // String strs[] = { "1", "2", "3", "4", "5" }; // Stats
13 Clases genéricas como parámetros de funcionesboolean sameAvg(Stats> ob) { if(average() == ob.average()) return true; else return false; } Por medio del tipo Stats> indicamos que esta función puede recibir un objeto de cualquier instancia de la clase genérica Stats
14 Clases genéricas como parámetros de funcionesInteger inums[] = { 1, 2, 3, 4, 5 }; Stats
15 Herencia y genéricos Véase el ejemplo de los apuntes de la asignatura (pags 75-79): Implementación de una clase genérica Cola.