genéricos

16
Genéricos Los métodos y clases ordinarios funcionan con tipos específicos: con tipos primitivos o con clases. Una de las formas en que los lenguajes orientados a objetos permiten la generalización es a través del polimorfismo. Los genéricos implementan el concepto de tipos parametrizados, que permiten crear componentes(especialmente contenedores) que resultan fáciles de utilizar con múltiples tipos. El termino "genérico significa perteneciente o apropiado a grandes grupos de clases". La intención original de los genéricos en los lenguajes de programación era dotar el programador de la mayor capacidad expresiva posible a la hora de escribir clases o métodos, relajando las restricciones que afectan a los tipos con los que esas clases o métodos pueden funcionar. Existen una serie de convenciones para nombrar a los genéricos: E – Element (usado bastante por Java Collections Framework) K – Key (Llave, usado en mapas) N – Number (para números) T – Type (Representa un tipo, es decir, una clase) V – Value (representa el valor, también se usa en mapas) S,U,V etc. – usado para representar otros tipos. Genéricos Simples Java Generics o simplemente clases Genéricas. Vamos a escribir algunos artículos hablando de este tema .Para empezar con ello vamos a construir la clase Bolsa que es una clase sencilla que nos permitirá almacenar objetos de varios tipos.

Upload: mario-estrada

Post on 13-Jul-2016

4 views

Category:

Documents


2 download

DESCRIPTION

Es un ensayo de java y habla acerca de las tipos genéricos para trabajar en netbens

TRANSCRIPT

Page 1: Genéricos

Genéricos

Los métodos y clases ordinarios funcionan con tipos específicos: con tipos primitivos o con clases.Una de las formas en que los lenguajes orientados a objetos permiten la generalización es a través del polimorfismo.Los genéricos implementan el concepto de tipos parametrizados, que permiten crear componentes(especialmentecontenedores) que resultan fáciles de utilizar con múltiples tipos.

El termino "genérico significa perteneciente o apropiado a grandes grupos de clases".

La intención original de los genéricos en los lenguajes de programación era dotar el programador de la mayor capacidad expresiva posible a la hora de escribir clases o métodos, relajando las restricciones que afectan a los tiposcon los que esas clases o métodos pueden funcionar.

Existen una serie de convenciones para nombrar a los genéricos:E – Element (usado bastante por Java Collections Framework)K – Key (Llave, usado en mapas)N – Number (para números)T – Type (Representa un tipo, es decir, una clase)V – Value (representa el valor, también se usa en mapas)S,U,V etc. – usado para representar otros tipos.

Genéricos SimplesJava Generics o simplemente clases Genéricas.Vamos a escribir algunos artículos hablando de este tema .Para empezar con ello vamos a construir la clase Bolsa que es una clase sencilla que nos permitirá almacenar objetos de varios tipos.

Esta clase tendrá un límite de objetos a almacenar . Alcanzado el limite no se podrán añadir mas .Vamos a ver su código fuente:

Page 2: Genéricos

123456789101112131415161718192021222324252627282930

package com.arquitecturajava;

import java.util.ArrayList;import java.util.Iterator;

public class Bolsa implements Iterable{

private ArrayList lista= new ArrayList();private int tope;

public Bolsa(int tope) {super();this.tope = tope;}public void add(Object objeto ) {if (lista.size()<=tope) {

lista.add(objeto);}else {

throw new RuntimeException("no caben mas");}

}

public Iterator iterator() {return lista.iterator();}

}

En nuestro caso vamos a disponer de dos clases con las cuales rellenar la bolsa . La clase Golosina y la clase Chocolatina.

Vamos a ver su código fuente : 123456

package com.arquitecturajava;

public class Chocolatina {

private String marca;

public String getMarca() {

Page 3: Genéricos

7891011121314151617181920

return marca;}

public void setMarca(String marca) {this.marca = marca;}

public Chocolatina(String marca) {super();this.marca = marca;}

}

123456789101112131415161718192021222324

package com.arquitecturajava;

public class Golosina {

private String nombre;

public String getNombre() {return nombre;}

public void setNombre(String nombre) {this.nombre = nombre;}

public Golosina(String nombre) {super();this.nombre = nombre;}

}

&nbsp;

&nbsp;

Es momento de crear un sencillo programa que llene la Bolsa de Chocolatinas y Golosinas para luego recorrer los elementos que están en la bolsa y sacarlos por pantalla.1234567

package com.arquitecturajava;

public class Principal {

 public static void main(String[] args) {

 Bolsa bolsa= new Bolsa(5); Chocolatina c= new Chocolatina("milka");

Page 4: Genéricos

89101112131415161718192021222324252627282930313233343536

 Chocolatina c1= new Chocolatina("milka"); Chocolatina c2= new Chocolatina("ferrero"); Golosina g1= new Golosina("gominola"); Golosina g2= new Golosina("chicle");

 bolsa.add(c); bolsa.add(c1); bolsa.add(c2); bolsa.add(g1); bolsa.add(g2);

 for (Object o :bolsa) {

 if( o instanceof Chocolatina) {

 Chocolatina chocolatina= (Chocolatina)o; System.out.println(chocolatina.getMarca());

 }else {

 Golosina golosina= (Golosina)o; System.out.println(golosina.getNombre()); } }

 }

}

El programa funcionará correctamente, pero nos podremos dar cuenta que resulta bastante poco amigable la estructura if /else en la cual se chequean cada uno de los tipos a la hora de presentarlo por pantalla.

Para solventar este problema podemos construir una clase Genérica .Este tipo de clase nos permitirá definir una Bolsa de un tipo concreto . Puede ser una bolsa de Golosinas o una bolsa de Chocolatinas pero NO de las dos cosas  a la vez .Esto en un principio puede parecer poco flexible pero si nos ponemos a pensar cuando programamos solemos imprimir una lista de Facturas o una lista de Compras no una lista mixta. Así pues el enfoque parece razonable. Vamos a ver el código fuente y comentarlo:1234567

package com.arquitecturajava.genericos;

import java.util.ArrayList;import java.util.Iterator;

public class Bolsa<T> implements Iterable<T>{

private ArrayList<T> lista= new ArrayList<T>();

Page 5: Genéricos

8910111213141516171819202122232425262728293031

private int tope;

public Bolsa(int tope) {super();this.tope = tope;}public void add(T objeto ) {if (lista.size()<=tope) {

lista.add(objeto);}else {

throw new RuntimeException("no caben mas");}

}

public Iterator<T> iterator() {return lista.iterator();}

}

La clase es un poco peculiar ya que al no saber de entrada de que tipo va a ser la bolsa debemos declarar un tipo Genérico T a nivel de clase y que será repetido en cada uno de los métodos que lo usen.

 De esta manera cuando construyamos un objeto de esta clase será el momento de especificar el tipo de Bolsa que deseamos .En el siguiente ejemplo hemos elegido “Chocolatina” como tipo para la Bolsa . De esta manera la bolsa solo admitirá este tipo de objetos.

Page 6: Genéricos

1234567891011121314151617181920212223242526

package com.arquitecturajava.genericos;

import com.arquitecturajava.Chocolatina;import com.arquitecturajava.Golosina;

public class Principal {

public static void main(String[] args) {

Bolsa<Chocolatina> bolsa= new Bolsa<Chocolatina>();Chocolatina c= new Chocolatina("milka");Chocolatina c1= new Chocolatina("milka");Chocolatina c2= new Chocolatina("ferrero");

bolsa.add(c);bolsa.add(c1);bolsa.add(c2);

for (Chocolatina chocolatina:bolsa) {

System.out.println(chocolatina.getMarca());}

}

}

Acabamos de construir nuestra primera clase Generica y hemos usado un bucle forEach para recorrerla de una forma sencilla.

Page 7: Genéricos

Tuplas:Es un grupo de objetos que se envuelven juntos dentro de otro objeto único.El receptor del objeto estará autorizado a leer los elementos, pero no a introducir otros nuevos( esteConcepto también se conoce como Objeto de transferencia de datos o Mensajero).Tuplas puede tener, normalmente, cualquier longitud, y cada objeto de la tupla puede tener un tipo distinto.Para tratar con el problema de las múltiples longitudes, podemos crear múltiples tuplas diferentes.He aquí una que almacena dos objetos.

//: net/mindview/útil/Twotuple.javaPublic class TwoTuple<A,B> {Public final A first;Public final B second;Public TwoTuple (A a, B b) ( first = a; second = b;)Public String ToString () {Return “{“+ first + “,”+ second +”}”;}}///:-

Pilas - Stack:

La clase Stack que implementaba la pila se construyo componiendo una clase genérica(Stack<T>) con otra clase genérica(LinkedList<T>).

En dicho ejemplo, observar que ( con unas cuantas excepciones que posteriormente realizaremos) un tipo genérico no es otra cosa que un tipo normal.

//: generics/LinkedStack.java//Una pila implementada con una estructura enlazada interna.

public class LinkStack<T> {pirvate static class Node<U> (U item;Node <U> next;Noode ( U item, item, Node <U> next) { this.item = item;this.next = next;}boolean end () (return item == null && next == null;)}pirvateNode <T> top = new Node <T> (); // Indicador de fin

Page 8: Genéricos

public void push(T item) {top = new Node <T> (item, top);

}public T pop {T result + top.item;if (!top.end()}top = top.next;return result;}Public static void main (String [] args) {LinkedStack<String> lss = new LinkedStack<String> ();for (String s ;"Phasers on stun!".split("")}lss.push(s);String s;while{(s=lss.pop() !=null)System.out.println(s);}/* Output:}stun!on Phasers*/////:-

La clase interna Node También es un genérico y tiene su propio parámetro de tipo.

Este ejemplo hace uso de un indicador de fin para determinar cuando la pila es vacía.

RamdonLisT:

Ahora para expandir las funcionalidades de la clase desarrollamos un método que recibe y procesa u item de un tipo generico:

public class miClase<T> {private ArrayList<T> lista;

public miClase() {lista = new ArrayList<T>();}

public void add(T element) {lista.add(element);Recordemos que no estamos tratando “explícitamente” con una clase llamada T. De hecho T es una convención para cualquier clase usada cuando alguien crea una instancia de miClase (La especificación Java permite utilizar cualquier identificador que deseemos).

Page 9: Genéricos

Interfaces Genéricas:Las interfaces genéricas se declaran de la "misma manera" que una clase genérica, veamos la sintaxis general:

interface nombre-interfaz<T1, T2, T3...>{ metodo1(); metodo2();…}Donde T1, T2, T3... son los tipos parametrizados.Aunque no siempre se así, una clase que implementa esta interfaz debe ser en forma general:

class nombre-clase<T1, T2, T3...> implements nombre-interfaz<T1, T2, T3...>{ metodo1Implementado(){} metodo2Implementado(){}…}

Si crea una clase genérica en Java (la clase de los parámetros de tipo genérico), puede utilizar los métodos genéricos (el método tiene parámetros de tipo genérico)?

Métodos Genéricos:Un método genérico que el método varié independientemente de la clase.

Considere el siguiente ejemplo:

public class MyClass { public <K> K doSomething(K k){ return k; }}

public class MyGenericClass<T> { public <K> K doSomething(K k){ return k; }

public <K> List<K> makeSingletonList(K k){ return Collections.singletonList(k); }}Como es de esperar en un método genérico, puedo llamar a doSomething(K) en las instancias deMyClass con cualquier objeto:

La Clase GenericMethods no está parametrizada, aunque es perfectamente posible parametrizar simultáneamente tanto una clase como sus métodos.

Page 10: Genéricos

Varargars y métodos Genéricos:

Los método genericos y las listas de argumentos variables pueden coexistir perfectamente:

Un método para utilizar con gneradores:

Resulta bastante cómo utilizar un generador para rellenar un objeto Collection, y también tiene bastante sentido hacer genérica esta operación:

Page 11: Genéricos

Un generador de propósito general:

Esta clase proporciona una implementación básica que producirá objetos de una clase que(1) sea pública (ya que BasicGenerator esta en un paquete separado. La clase en cuestión debe tener acceso público y no simplemente de paquete) y (2) tenga un constructor predeterminado ( uno que no tome ningún argumento).

Page 12: Genéricos

Una Utilidad SET

Otro ejemplo del uso método genérico. Estos conjuntos pueden definirse de forma cómoda como método genérico, para utilizarlos con todos los diferentes tipos:

Los primeros tres métodos duplican el primer argumento copiando sus referencias en un nuevo objeto HashSet, de modo que los conjuntos utilizados como argumentos no se modifican directamente. El valor de retorno será, por tanto, un nuevo objeto Set.Los cuatro métodos representan las operaciones matemáticas de conjuntos: unión() devuelve un objeto Set que contiene la combinación, Difference() resta los elementos subset de superset complemente() devuelve un objeto Set con todos los elementos que no conformen parte de la intersección.

Page 13: Genéricos

Clases internas anónimas:Los genéricos también pueden utilizarse con las clases internas y con las clases internas anónimas.He aquí un ejemplo de implementa la interfaz Generator utilizando clases internas anónimas.

Tanto Customer como Teller tienen constructores privados, lo que nos obliga a utilizar objetos Generator. Customer tiene un método generator() que genera un nuevo método Generator<Customer> cada vez que lo invocamos. Puede que no necesitemos múltiples objetos Generator, y Teller crea un objeto generator público.

Puesto que el método generato() de Customer como el objeto Generator de Teller son estáticos, no puedenFormar parte de una interfaz, asi que no hay forma de hacer genérica esta función concreta. A pesar de ello funciona razonablemente bien con el método fill().