16.1 INTRODUCCIÓN PROGRAMACIÓN GENÉRICA

 

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