|
JSem: 4.3 |
L'abbiamo già detto, per implementare un'interfaccia bisogna definire tutti i suoi metodi. Per esempio nel caso di MouseListener, anche se siamo interessati solo nel metodo mousePressed, bisognerà definire gli altri quattro metodi dell'interfaccia. Una possibilità è di lasciarli vuoti, l'alternativa è di usare la corrispondente classe MouseAdapter, infatti l'AWT fornisce, per ogni interfaccia con più di un metodo, una classe Adapter che implementa l'interfaccia e che è già predisposta con i vari metodi definiti vuoti, rimane solo da definire i metodi che interessano; questo si fà estendendo la corrispondente classe adapter. Per usare, per esempio, MouseAdapter definendo solo il metodo mousePressed: public class MyMousePressed extends MouseAdapter{ public void mousePressed(MouseEvent e){ ...//codice } } A questo punto ci sono varie posibilità per estendere la classe Adapter: Una classe interna è una classe definita all'interno di un'altra classe. L'uso delle classi interne ha i suoi pregi e i suoi difetti. Pregi: rende il codice più compatto, in un certo senso più chiaro. Permette di superare tranquilamente problemi legati alla non multi-ereditarietà in Java. Difetti: in un primo tempo può confondere; il codice non è facilmente riutilizzabile (e questo non è poco). Certi compilatori (versione 1.1) non permettono l'accesso alle variabili d'istanza da parte di classi interne; con Java2 (1.2.x) una classe interna (purchè non static) può accedere a variabili di istanza e metodi come se il suo codice facesse parte della classe che la contiene. Vediamo queste varie possibilità su un esempio semplice: un'applet con una label con una scritta "premi", quando si preme il mouse sulla scritta, lo sfondo della label diventa rosso. Con una classe esterna:
Salvare questo file come "ProvaAdapter.java" e compilarlo; dopo la compilazione troverete nella vostra cartella di lavoro due files .class: ProvaAdapter.class e MyMseAdapter.class Il file "eseguibile" è ProvaAdapter.class Con una classe interna:
Il codice è più compatto. Salvare questo file come "ProvaAdapter2.java" e compilarlo. Dopo la compilazione troverete un file ProvaAdapter2.class e un file ProvaAdapter2$MyMAd.class Il simbolo $ sta a indicare che MyMAd è una classe interna di ProvaAdapter2. Se provate a istanziare un oggetto ProvaAdapter2$MyMAd in un'altra classe, il compilatore vi darà un errore: No enclosing instance of class ProvaAdapter2 is in scope; an explicit one must be provided... Con una classe interna anonima:
Il codice è ancora più compatto. Salvare questo file come "ProvaAdapter3.java" e compilarlo. Dopo la compilazione troverete un file ProvaAdapter3.class e un file ProvaAdapter3$1.class Infatti la classe interna non ha nome (è anonima "anonymous inner class"), $1 sta ad indicare che questa è la prima classe interna anonima di ProvaAdapter3.class L'istruzione }); è tipica delle classi interne anonime: Prossimamente (Applet o applicazione?) vedremo un uso frequente di adapter e classi interne anonime nel caso di WindowListener (che ha ben sette metodi!). |
next content previous