¿Qué es la programación genérica?
La programación genérica surge a partir de la versión 5.0 de java en el
año 2004. Es un paradigma informático que nos indica que tenemos que crear un
código que podamos reutilizar para otros objetos de diverso tipo. Por ejemplo
el objeto ArrayList lo podemos utilizar para manejar y reutilizar objetos de
tipo String, coche, moto….
Le pasaríamos por parámetros entre corchetes angulares <> el objeto al objeto ArrayList. Así
conseguimos reutilizar el objeto ArrayList con cualquier objeto. El objeto pasado
al ArrayList entre corchetes angulares <> se llama parámetro de tipo.
|
parámetros de tipo en programación genérica de java |
Tenemos que tener en cuenta que
no podemos pasar como parámetro tipo una
clase primitiva(int, long,
boolean,double…)
VENTAJA DE LA PROGRAMACIÓN GENÉRICA
Esto mismo lo podríamos realizar
utilizando una propiedad de java que es la herencia pero tendríamos que realizar
uso continuo del
casting. Por otra parte cuando heredas un objeto y le haces un
casting el fallo no saldría en tiempo de compilación si no en tiempo de
ejecución y esto haría más complicado controlar los posibles
errores. Todo esto
hace mas complejo de nuestro código.
Utilizar la programación genérica:
·
Hace nuestro código más sencillo.
·
Podemos reutilizar código de una forma más
rápida.
·
Los errores nos acontecerán en la
compilación, el IDE (entorno desarrollo) nos avisará y podremos rectificar
antes de programar más líneas de código.
·
Al pasar un parámetro tipo queda más claro
en nuestro código que tipo de dato estamos manejando.
Como crear mi clase genérica
Crearremos una clase y le
pasarémos por parámetro tipo nuestro objeto. Es una buena praxis el pasarle una
letra mayúscula que suele ser T, U,K.
Podemos utilizar cualquier otra y no afectará a nuestro código pero es
aconsejable pasarle estas para que el resto de programadores identifiquen que
son.
public class ClaseGenericaaaaaaa <Q>{
}
Creamos
una variable de tipo de tipo Q y un constructor.
public class ClaseGenericaaaaaaa <Q>{
private Q xxxx;
public ClaseGenericaaaaaaa() {
xxxx = null;
}
}
public
class ClaseGenericaaaaaaa <Q>{
private
Q xxxx;
//**constructor**
public ClaseGenericaaaaaaa() {
xxxx = null;
}//**setter
public void setClaseGenericaaaaaaa (Q xxxx ) {
this.xxxx = xxxx;
}//getter
public Q getClaseGenericaaaaaaa
() {
return xxxx;
}
}
Nos iremos al método
main crearemos un objeto de la clase ClaseGenericaaaaaaa al que le pasamos por parámetro de
tipo un String.
public class eSTOva {
public static void main(String[] args) {
//le decimos que Q
será un String
ClaseGenericaaaaaaa
<String> CrearString = new ClaseGenericaaaaaaa<String>();
//establecemos dato guardado
CrearString.setClaseGenericaaaaaaa("DDDDDDDDDDDDDDD");
//lo recuperamos para imprimirlo
System.out.println(CrearString.getClaseGenericaaaaaaa());
}
}
Antes le pasamos un parámetro tipo de String, pero puede ser un File o cualquier otro que deseemos.
public class eSTOva {
public static void main(String[] args) {
ClaseGenericaaaaaaa
<String> CrearString = new ClaseGenericaaaaaaa<String>();
ClaseGenericaaaaaaa
<File> RutaAcceso = new ClaseGenericaaaaaaa<File>();
CrearString.setClaseGenericaaaaaaa("DDDDDDDDDDDDDDD");
RutaAcceso.setClaseGenericaaaaaaa(new File("C:"+File.separator+"Users" +File.separator+"dagip"
+File.separator+"Desktop" +File.separator+"BOGEER" +File.separator+"imagenes"
+File.separator+"video"));
//nos
regresa un String
System.out.println(CrearString.getClaseGenericaaaaaaa());
//nos
regresa un File
System.out.println(RutaAcceso.getClaseGenericaaaaaaa());
}
}
Al ser un objeto de tipo File podemos decir lo siguiente, porque posee
métodos de la clase File. Tenemos las ventajas de la herencia sin tener los
problemas del casting.
System.out.println(RutaAcceso.getClaseGenericaaaaaaa().getAbsolutePath());
CREAR UN MÉTODO GENÉRICO
Es un método que podemos utilizar
con cualquier tipo de objeto, no es
necesario que se generado dentro de una clase genérica, lo podremos
construir en cualquier tipo de clase. Y se adptará al objeto que le pasemos por
parámetro tipo. No se le puede pasar un tipo de dato primitivo.
Su sintaxis es
similar a la utilizada en una clase genérerica.
public static <K> String getdato (K variable){
return "Este es tu dato " + variable;
}
Si deseamos que nos regrese un dato sin especificar que
sea igual al objeto que recibe
public static <K> K getdato (K variable){
return "Este es tu dato " + variable;
}
Ahora lo utilizamos, nos imprimiría
en la ventana de inmediato lo que tenemos en ambas variables a pesar que una
es File y la otra String y sin hacer un casting:
System.out.println(eSTOva.getdato(CrearString));
System.out.println(eSTOva.getdato(RutaAcceso));
HERENCIA DE CLASES GENÉRICAS Y TIPOS COMODÍN
La herencia en las clases genéricas no es igual al que tiene
en el resto de clases. Esta anomalía a la hora de heredar de una clase genérica
nos obligar
Recordemos que en una clase normal existía el pricipio de
sustitución
Principio de sustitución: Se puede
utilizar un objeto de una sub clase siempre que el programa espere un objeto de
la Superclase. Por lo que un objeto se puede comportar de diferente manera
dependiendo del contexto. Podremos utilizarlo siempre que podamos decir ES UN. En el siguiente caso podemos
decir cerdo es carne y pollo es carne.
Carne [] Cerdo=new
Carne[5];
Carne [] Pollo =new
Carne[6];
Carne [] ArticulosCarne=new
Carne[11];
for (int x=0; x<5; x++) {ArticulosCarne[x]= Cerdo[x];}
for
(int y=5,x=0;y<11
&& x<6;y++,x++){ArticulosCarne[y]=Pollo[x];}
En las clases genéricas no existe
relación entre los objetos. La Clase <carner> es un objeto con unas
propiedades y métodos, la Clase <cerdo> es otro objeto independiente con
unas propiedades y métodos, pero no tienen ningún nexo en común.
Para tener una salida a esto tenemos la posibilidad de crear
un método genérico en la clase padre y pasarle por parámetros la clase hija.
Luego iremos al método main y llamaremos a ese método.
ClaseGenericaaaaaaa < ArticulosCarne []> CrearString = new
ClaseGenericaaaaaaa< ArticulosCarne []>();
ClaseGenericaaaaaaa < Pollo []> CrearString = new
ClaseGenericaaaaaaa< Pollo []>();
ClaseGenericaaaaaaa < Cerdo []> CrearString = new
ClaseGenericaaaaaaa< Cerdo []>();
Creamos el método diciéndole que hereda de ArticulosCarne
public static void getid(ClaseGenericaaaaaaa <? extends ArticulosCarne > p ) {
Pollo heredaCarne = p.getClaseGenericaaaaaaa();
System.out.print(nod);
}
Ahora podemos
utilizar el getClaseGenericaaaaaaa() en el método main.
NUMERO1.setClaseGenericaaaaaaa(Pollo ());