Java fornisce un meccanismo per dichiarare e istanziare una classe allo stesso tempo. Queste classi prendono il nome di classi anonime, poiché sono delle classi locali, dichiarate all’interno di un metodo, senza nome.
Vengono utilizzate quando si ha la necessità di avere una classe che serve solo in quel punto e in quel momento; è quindi inutile scrivere una normale classe che non verrà mai riutilizzata. E’ come se fossero delle classi usa e getta.
Un grande vantaggio è la lunghezza del codice, molto più breve e compatto rispetto a dover scrivere un’intera classe da zero.
La sintassi per creare una classe anonima corrisponde alla chiamata di un costruttore, seguita da un blocco di codice che estende la classe stessa (o implementa metodi nel caso si crei una istanza anonima di una interfaccia).
Nel caso di estensione di una classe si ha:
new class-name ( [ argument-list ] ) { class-body }
Nel caso di implementazione di una interfaccia:
new interface-name () { class-body }
Esempio
public class A { public void f() { System.out.println("A"); } public static void main(String[] args) { A tfc = new AEstesa(); //estendere A override di f() A tmp = new A() { public void f() { System.out.println("override"); } }; tmp.f(); } }
La variabile tmp è una istanza di una classe anonima, che estende A e ridefinisce il metodo f().
Teoricamente è possibile aggiungere dei nuovi metodi ad una classe, diversi da quelli ereditati. Tuttavia, non è conveniente farlo perché questi metodi non possono essere richiamati, essendo il riferimento della classe anonima del tipo della superclasse.
Esempio:
public class A { public void f() { System.out.println("A"); } public static void main(String[] args) { A tfc = new AEstesa(); //estendere A override di f() A tmp = new A() { public void f() { System.out.println("override"); } public void g() { } }; tmp.g();// errore di compilazione: il metodo g() non è richiamabile. tmp vede solo // i metodi presenti nella classe A } }