Bienvenidos a todos a un nuevo bloque
de programación en Java, antes de nada agradeceros que sigáis el blog es
recomendable que a la par de que lo estéis leyendo hagáis la práctica al mismo
tiempo para verlo más claro y sobre todo para que se os haga más ameno porque
entiendo que hay algunos posts que son muy largos y ya el mero hecho de verlos
a primera vista te echa un poco para atrás, pero bueno siguiendo la práctica
conforme indica el post no son tan largos.
Bueno vamos a lo que vamos que es a un
nuevo bloque dedicado a la Programación Genérica. La programación genérica
consiste en escribir un código de programación que puedas reutilizar para
objetos de diversos tipos. La clave está en la reutilización del código, de
esta forma utilizando programación genérica evitas el tener que crear una clase
diferente para cada tipo de objeto que vayas a manejar, es decir, si en un
momento concreto necesitas manejar objetos de tipo String pues te evitas tener que crear una clase en concreto para
manejar ese tipo de objetos.
De tal forma que utilizando la clase ArrayList que vimos en el bloque
anterior podemos reutilizarla para
almacenar y manipular objetos de tipo String
como para almacenar y manipular objetos de tipo File. Esto lo hacemos en la clase ArrayList modificando lo que se denomina parámetro de tipo, el
parámetro de tipo es el parámetro que va dentro de corchetes angulares, lo que
está sombreado en amarillo:
ArrayList <String> archivos = new ArrayList <String>();
Este ArrayList podría ser también de
tipo File:
ArrayList <File> archivos = new ArrayList <File>();
La duda que surge en este instante es
si no se puede hacer lo mismo manejando objetos en general con una única clase
sin utilizar este paradigma de la programación genérica. La respuesta es que
sí, se puede hacer utilizando una característica muy importante y potente que
es la herencia, utilizando la herencia podemos utilizar una única clase que sea
capaz de manejar objetos de diferente tipo, sin embargo, hacerlo de esta forma
trae consigo varios inconvenientes:
·
Uso
continuo del casting
·
Complicación
del código
·
No
posibilidad de comprobación de errores
Por lo que se recomienda el uso de la
programación genérica siendo sus ventajas las siguientes:
·
Mayor
sencillez del código
·
Reutilización
del código en numerosos escenarios
·
Comprobación
de errores en tiempo de compilación
Vamos a ver todo esto mediante un
ejemplo que va a consistir en imaginarnos que no tenemos en la API de Java la clase ArrayList, la programación genérica
surgió a partir de la versión 5.0 de Java antes de esta versión no existía la
programación genérica con lo cual antes de esta versión no existía la clase ArrayList como la conocemos ahora, pues
nos vamos a imaginar que estamos en esa situación, en una versión anterior a la
5.0 de Java.
Nos creamos un proyecto nuevo al que
vamos a llamar ProgramacionGenerica,
dentro de este proyecto un paquete al que vamos a llamar arraylist y una clase ArrayList
siendo el código el siguiente:
package arraylist;
public class ArrayList {
public ArrayList(int z) {
datosElemento = new Object[z];
}
public Object get(int i){
return datosElemento[i];
}
public void add(Object o) {
datosElemento[i] = o;
i++;
}
private Object [] datosElemento;
private int i=0;
}
La clase ArrayList tiene un constructor que va a recibir un argumento de
tipo entero, tenemos definido un array
al cual he denominado datosElemento,
¿qué hace el constructor? Si le pasamos, por ejemplo, un 3 le estamos diciendo
que este array de objetos va a tener 3 elementos. El método get() nos va a devolver un elemento
concreto del array. Y el método add()
va añadir un nuevo elemento.
Luego hay otro segundo fichero UsoArrayList con el método principal main cuyo código es el siguiente:
package arraylist;
import java.io.*;
public class UsoArrayList {
public static void main(String[] args) {
}
}
En esta clase vamos almacenar objetos
de tipo String. Lo primero es
instancia la clase ArrayList llamar
al constructor donde le pasábamos un argumento de tipo entero:
package arraylist;
import java.io.*;
public class UsoArrayList {
public static void main(String[] args) {
ArrayList archivos
= new ArrayList(4);
}
}
Le indicamos que va a contener cuatro
elementos. Con el método add()
añadimos los elementos:
public static void main(String[] args) {
ArrayList
archivos = new ArrayList(4);
archivos.add("Paco");
archivos.add("Luis");
archivos.add("Ana");
archivos.add("Sonia");
}
Ahora lo que queremos ver es lo que tenemos almacenado en una posición en concreto por lo que tenemos que hacer uso del método get():
Por ejemplo, si queremos ver el
elemento que ocupa la posición 2:
public static void main(String[] args) {
ArrayList
archivos = new ArrayList(4);
archivos.add("Paco");
archivos.add("Luis");
archivos.add("Ana");
archivos.add("Sonia");
String nombrePersona
= archivos.get(2);
}
Creamos una variable de tipo String al que le pasamos el método get() para que nos imprima el elemento ubicado en la posición 2, sin embargo, nos da un error. El error que marca es el siguiente:
No se puede convertir un Objeto a String, el método get() hemos estado obligados a declararlo como tipo Object porque esta clase ArrayList debe ser capaz de manejar
cualquier objeto, si en el método en lugar de tipo Object le hubiéramos dicho de tipo String solo podría almacenar datos de tipo String lo que queremos es que almacene cualquier tipo de objeto,
esto nos obliga a hacer un casting:
String nombrePersona = (String) archivos.get(2);
Le indicamos que lo imprima por
consola:
System.out.println(nombrePersona);
Ejecutamos:
Sin en lugar de manejar datos de tipo String quisiéramos manejar datos de tipo
File lo haríamos de la siguiente
forma:
package arraylist;
import java.io.*;
public class UsoArrayList {
public static void main(String[] args) {
ArrayList
archivos = new ArrayList(4);
/*archivos.add("Paco");
archivos.add("Luis");
archivos.add("Ana");
archivos.add("Sonia");
String nombrePersona = (String) archivos.get(2);*/
archivos.add(new
File("prueba.txt"));
//System.out.println(nombrePersona);
}
}
Posteriormente tendríamos que indicar
el casting:
package arraylist;
import java.io.*;
public class UsoArrayList {
public static void main(String[] args) {
ArrayList
archivos = new ArrayList(4);
/*archivos.add("Paco");
archivos.add("Luis");
archivos.add("Ana");
archivos.add("Sonia");
String nombrePersona = (String) archivos.get(2);*/
archivos.add(new File("prueba.txt"));
File nombrePersona = (File) archivos.get(0);
//System.out.println(nombrePersona);
}
}
El programa funcionaría igual el único
inconveniente sería que tendríamos que indicar el casting, pero no sería el
único problema, supongamos que añadimos un nuevo elemento al ArrayList pero de tipo File:
package arraylist;
import java.io.*;
public class UsoArrayList {
public static void main(String[] args) {
ArrayList
archivos = new ArrayList(5);
archivos.add("Paco");
archivos.add("Luis");
archivos.add("Ana");
archivos.add("Sonia");
archivos.add(new File("pruebas.txt"));
String nombrePersona
= (String) archivos.get(4);
System.out.println(nombrePersona);
}
}
Fijaros que no nos da error en el código pero si lo ejecutamos nos da un error de excepción:
Esto ocurre porque está convirtiendo
un objeto de tipo File a String.
Esto no pasaría si utilizáramos la
clase ArrayList que tenemos en la API de Java desde la
versión 5.0 de Java esto es debido porque para declarar un ArrayList lo declaramos de la siguiente forma:
ArrayList <String> archivos =
new ArrayList <String>();
Entre corchetes le estamos indicando
que el ArrayList va a manejar objetos de tipo String con lo cual nos marcaría
un error de compilación si añadiéramos otro elemento de diferente tipo, por
ejemplo, un tipo de dato File.
La programación genérica a mí se me
hizo un poco enrevesado no os cortéis en preguntar cualquier duda, el blog lo
hice principalmente además de plasmar mis conocimientos de Java también el
podernos ayudar entre todos con dudas que nos puedan surgir. Os espero en el
próximo post, saludos!
15.3 ITERADORES << >> 16.2CREACIÓN CLASES GENÉRICAS
No hay comentarios:
Publicar un comentario