Adapter, classi interne.


Java Sun

Earthweb
(ex Gamelan)

Jars

Java Boutique

JavaWorld

PIP






  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:

  • con una classe esterna
  • con una classe interna
  • con una classe interna anonima


  • 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:

    
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class ProvaAdapter extends Applet{
    
    Label lab = new Label("premi");
    MyMseAdapter mslis = new MyMseAdapter();
    
    public void init(){
    	lab.addMouseListener(mslis);
    	add(lab);
    	}
    }
    
    
    class MyMseAdapter extends MouseAdapter{
    	public void mousePressed(MouseEvent e){
    		Component cp = e.getComponent();
    		cp.setBackground(Color.red);
    	}
    }

    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:

    
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class ProvaAdapter2 extends Applet{
    
    Label lab = new Label("premi");
    
    public void init(){
    	lab.addMouseListener(new MyMAd());
    	add(lab);
    	}
    
    class MyMAd extends MouseAdapter{
    	public void mousePressed(MouseEvent e){
    		Component cp = e.getComponent();
    		cp.setBackground(Color.red);
    		}//fine metodo mousePressed
    	}//fine classe interna
    }//fine applet
    

    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:

    
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class ProvaAdapter3 extends Applet{
    
    Label lab = new Label("premi");
    
    public void init(){
    	lab.addMouseListener(new MouseAdapter(){
    //inizio def classe anonima
    		public void mousePressed(MouseEvent e){
    		Component cp = e.getComponent();
    		cp.setBackground(Color.red);
    		}//fine metodo mousePressed
    	});//fine classe interna: } 
    //fine (new ...: ) fine istruzione: ;
    	add(lab);
    	}//fine init
    }//fine applet

    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:

  • la graffa } chiude la classe
  • la tonda ) chiude (new ...
  • il punto virgola ; chiude la riga d'istruzione


  • 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