Java Generics
Java permite que los programadores puedan crear clases, interfaces y métodos en los que el tipo de datos sobre los que operan se especifica como parámetro. Es decir, de tipos parametrizados.A estos se les denomina genéricos. Por ejemplo, una clase que maneja estos parámetros se denomina clase genérica, igualmente será con un método o interfaz.
Un método genérico debe ser declarado dentro de una clase o interfaz genérica. Para ello, empleamos la siguiente sintaxis:
// Clase genérica
public class Generico<T>
//Interfaz genérica
public interface Generico<T,E>
La ventaja del código que emplea estos métodos es que funcionará automáticamente con el tipo de datos pasados a su parámetro de tipo.
// Instanciación de la clase genérica
Generico<String> gen = new Generico<>();
// En este caso el tipo de dato es un String
Estos algoritmos son muy útiles para y se emplean muchísimo en las bibliotecas internas de Java como en las Colecciones o métodos de ordenamiento rápido.
Clase genérica simple- Código
Declaramos el tipo genérico T y un atributo de ese tipo llamado "atributo"
package clases;
public class Generico<T> {
private T atributo;
public Generico(T atributo) {
this.atributo = atributo;
}
public String getClase() {
return String.format("Clase: %s", this.atributo.getClass().getName());
}
public String getAtributo() {
return String.format("Contenido: %s", this.atributo.toString());
}
}
Prueba y resultado
Al crear objetos de estas clases genéricas podemos emplear 3 formas:
- Indicar dentro de la sintaxis diamante el tipo
- Usar el tipo desconocido ?, el constructor recibe el tipo de parámetro
- Obviar el tipo, el constructor recibe el parámetro y usa su tipo.
package test;
import clases.ContenedorGenerico;
import clases.Generico;
import clases.Operador;
public class Test {
public static void main(String[] args) {
Generico<String> gen1 = new Generico<>("Hola");
System.out.println(gen1.getClase());
System.out.println(gen1.getAtributo());
Generico<?> gen2 = new Generico(45d);
System.out.println(gen2.getClase());
System.out.println(gen2.getAtributo());
Generico gen3 = new Generico(true);
System.out.println(gen3.getClase());
System.out.println(gen3.getAtributo());
}
}
Clase: java.lang.String Contenido: Hola Clase: java.lang.Double Contenido: 45.0 Clase: java.lang.Boolean Contenido: true
Clase genérica con varios parámetros - Código
Podemos indicar más de un tipo genérico, estos van separados por comas.
package clases;
import java.util.HashMap;
import java.util.Map;
public class ContenedorGenerico<E,F> {
private Map<E, F> contenedor;
public ContenedorGenerico() {
this.contenedor = new HashMap<>();
}
public void agregar(E clave, F valor) {
this.contenedor.put(clave, valor);
}
public Map<E, F> getContenedor() {
return this.contenedor;
}
}
Prueba y resultado
Las colecciones emplean internamente las clases y métodos genéricos.
package test;
import clases.ContenedorGenerico;
import clases.Generico;
import clases.Operador;
public class Test {
public static void main(String[] args) {
ContenedorGenerico<Integer,String> contenedor = new ContenedorGenerico<>();
contenedor.agregar(12, "doce");
contenedor.agregar(11, "once");
contenedor.agregar(10, "diez");
contenedor.getContenedor().forEach((k,v)->{
System.out.println("Clave: "+k);
System.out.println("Valor: "+v);
});
}
}
Clave: 10 Valor: diez Clave: 11 Valor: once Clave: 12 Valor: doce
Clase genérica con parámetros limitados - Código
Para limitar el tipo de datos que se pueden recibir se utiliza la palabra reservada "extends" y luego la superclase. Por ejemplo, el siguiente código muestra una clase que solo permite tener parámetros de tipo numéricos.
package clases;
public class Operador<A extends Number, B extends Number> {
A valorA;
B valorB;
public Operador(A valorA, B valorB) {
this.valorA = valorA;
this.valorB = valorB;
}
public Double getSuma() {
return this.valorA.doubleValue() + this.valorB.doubleValue();
}
public Double getProducto() {
return this.valorA.doubleValue() * this.valorB.doubleValue();
}
}
Prueba y resultado
package test;
import clases.ContenedorGenerico;
import clases.Generico;
import clases.Operador;
public class Test {
public static void main(String[] args) {
Operador op1 = new Operador(4, 5);
System.out.println("Suma: " + op1.getSuma());
System.out.println("Producto: " + op1.getProducto());
Operador op2 = new Operador(4.6, 5);
System.out.println("Suma: " + op2.getSuma());
System.out.println("Producto: " + op2.getProducto());
Operador op3 = new Operador(2.5, 1.65);
System.out.println("Suma: " + op3.getSuma());
System.out.println("Producto: " + op3.getProducto());
}
}
Suma: 9.0 Producto: 20.0 Suma: 9.6 Producto: 23.0 Suma: 4.15 Producto: 4.125
No hay comentarios:
Publicar un comentario