Permettono di definire con una classe un insieme di classi su tipi diversi utilizzati all’interno della stessa: e’ un meccanismo molto potente con molti meccanismi sottili, alcuni da conoscere.
Tutte le collezioni che abbiamo visto ed utilizzato, sfruttano i Generics (parentesi triangolari).
Per creare un’istanza di classi con Generici, semplicemente creiamo un’istanza di una classe passando uno o più tipi fra parentesi angolari:
new ArrayList();
Per assegnare le variabili di tipi generici:
ListlistaDiStringhe = new ArrayList ();
Possiamo anche prendere input di tipi generici:
public void metodo (Lislista) { //... }
Definire una classe Generica
Specifichiamo il nome della classe con affianco uno o più tipi separati da virgola.
public class Coppia{ private T a,b; public Coppia(T a, T b) { this.a = a; this.b = b; } public T getPrimo() { return a; } public T getSecondo() { return b; } }
Per utilizzarla invece:
Coppiac1 = new Coppia (10, 20); Coppia c2 = new Coppia (10.5, 20.5);
Il controllo sulla corrispondenza fra valore attuale e parametro del metodo viene fatto in compilazione.
Per specificare più tipi generici invece
public class Coppia{ private T a private S b; public Coppia(T a, S b) { this.a = a; this.b = b; } public T getPrimo() { return a; } public S getSecondo() { return b; } }
Estendere classi Generiche
Possiamo estendere le classi generiche in questo modo:
public class Orario extends Coppia{ public Orario(Integer a, Integer b) { super(a,b); } }
O una classe Data:
public class Data extends Coppia> { public Data(Integer giorno, Integer mese, Integer anno) { super(giorno, new Coppia (mese,anno); } }
Esercizio: Lista Linkata generica
Non posso instanziare un tipo generico con un tipo primitivo: devo essere sicuro che almeno i metodi della classe object li possieda.
Alcuni esempi di interfaccie generiche:
public interface List { void add(e,x); Iterator iterator(); } public interface Iterator { E next(); boolean hashNext(); }
Principalmente i generics vengono utilizzate nelle collezioni (Collections).
Ad esempio, l’ intestazione della classe ArrayList:
public class ArrayListextends AbstractList implements List , RandomAccess, Cloneable, Serializable
Se devo definire solo un metodo con un tipo generico invece, posso fare così:
static public void esamina(ArrayListlista) { for (T o : lista) { System.out.println(o.tostring()); } }