Newsgroup: it.comp.java
Titolo: Inner class

Scusate la domanda forse banale, ma come si fa da una inner class, per
esempio da una derivata da AbstractAction, ad accedere ai metodi ed ai
membri della classe esterna (tipo la Jframe del mio caso)?
Grazie e scusate l'ignoranza ^_^

 wrote in message
news:5BE18.2515$RQ5....@news1.tin.it...

Forse sara' una soluzione rozza, dato che programmo da poco, ma ho risolto
creando un metodo statico richiamato
Es.
Class Esecuzione
....
public static void esegui(){
    ...
}
.....
Nell'altra classe
    Esecuzione.esegui();
Ciao !
--
|  
http://digilander.iol.it/iccp/
 ( FAQ di ICCP )  U.I.N. Icq : 41710019
|  
http://digilander.iol.it/videocdpsx
 ( Crea Video CD per PSX )
|  
http://setiathome.ssl.berkeley.edu/stats/team/team_7422.html
|  
http://www.utenti.org
 I.T.T.ISDN FAQ -> 
http://www.sistemista.com

 ha scritto:

Chi sostiene di non essere ignorante probabilmente è il peggiore
ignorante, perchè ignora la propria ignoranza ;-)
Comunque non la ritengo una domanda banale (io in passato ho
convissuto con tale ignoranza per parecchi mesi utilizzando soluzioni
alternative e senza morirci ;-) ): è uno di quei dettagli che pochi
libri riportano e comunque sfugge facilemente anche ad un lettore
attento perchè poco usato (di rado si progettano classi interne che
necessitino del reference dell'istanza padre, e principalmente ciò
capita nelle GUI - Swing,AWT- quando si vuole liquidare un listener in
2 secondi usando comode ma talvolta sconvenienti classi anonime ).
Ovviamente per i metodi/attributi NON sovraccaricati/ridefiniti
è sufficiente richiamarli come se fossero stati ereditati:
class A {
  public void dummy();
  class B {
    B() { dummy(); } // ho richiamato un metodo di A
                     // come fosse suo
  }
}
Il tuo principale problema è però ottenere il reference dell'oggetto
padre.
Se "B" è una inner class di un istanza "a" di "A", è sufficiente
chiamare l'istanza padre come "A.this".
(-1-)
class A {
  int iValue;
  class B {
    public String toString() { 
      return String.valueOf( A.this.iValue ); 
    }
  }
}
Attenzione però che tu stia lavorando con inner classes non statiche,
perchè altrimenti le inner classes non sono associate a nessuna
istanza e diventa un errore chiamare "A.this"
(-2-)
// A.this ==> ERRORE IN TAL CASO
class A {
  int iValue;
  static class B {
    public String toString() { 
      return String.valueOf( A.this.iValue ); 
    }
  }
}
Per creare una nuova istanza di una inner class B, è sufficiente fare,
nei 2 casi di classe interna non statica o statica rispettivamente
(-1-)  A a = new A();  a.new B()    opp.   new A().new B()
(-2-)  new A.B()
Qualche problema in più può sorgere se la classe esterna è anonima ;-)
, perchè non è più possibile indirizzarla con un nome definito.
Ricordati comunque che le inner classes hanno visibilità completa su
tutte le variabili/metodi della classe/istanza padre, e che quindi
usarle comporta sempre il rischio di concedere delle "vie facili" per
accedere a metodi/variabili che normalmente dovrebbero essere privati
della classe padre.
Per concludere, il comportamento descritto è valido anche per le
classi innestate nei metodi; ti riporto un esempio inconcludente
(un'autentica porcata) solo per mostrare un sunto di quanto detto:
class Test {
  public String toString() {
    class A {
      private final int iValue;
      A( int iValue ) { this.iValue = iValue; }
      class B { 
        public String toString() { 
          return "Value of A: "+ A.this.getValue();
        }
      }
      public String getValue() {
        return new Object() {
          public String toString() {
            return String.valueOf(A.this.iValue);
          }
        }.toString();
      }
    }
    return new A(5).new B().toString();
  }
}
Ciao, Max.

2 secondi usando comode ma talvolta sconvenienti classi anonime ).
[CUT]
E' l'uso piů evidente, ma per quanto riguarda il valore "concettuale" 
metterei prima l'uso di inner class come (es.) itaratori (Iterator, 
Enumeration, ecc.).
Giusto i miei 2 cent di euro ;-)
-- 
Ciao
	Fabrizio C.

 membri della classe esterna (tipo la Jframe del mio caso)?
Supponendo sia public o comunque accessibile, dipende se l'inner class e' 
statica o no. 
Se e' statica, si fa come per una classe "normale" - semplicemente il nome, 
invece di essere nella forma <class> e' nella forma <outer class>.<inner 
class>. Ad esempio con
public class MiaClasse { 
  public static class ClasseInterna { } 
}
usi new MiaClasse.ClasseInterna() per creare un'istanza di 
MiaClasse.ClasseInterna. - e poi vi accedi in modo normale.
Se la classe non e' static, significa che *per creare un'istanza della 
classe interna ti serve un'istanza della classe esterna*. I dettagli del 
perche' e percome li trovi nella documentazione - in soldoni un'inner class 
nonstatic ha senso solo nel contesto di un'istanza della classe 
contenitrice.
Ora, ci sono due modi per creare e riferirsi ad un'oggetto inner: nel codice 
della classe contenitrice, usi semplicemente il nome della classe:
public class MiaClasse { 
  public class ClasseInterna { public void metodo() { } } 
  public ClasseInterna crea() { return new ClasseInterna(); }
}
Dall'esterno, lo crei con una sintassi un po' particolare: <oggetto di 
classe esterna>.new <inner class> - dopodiche' lo usi come ogni altro 
oggetto
public void metodoAlDiFuoriDiMiaClasse() {
  MiaClasse mc = new MiaClasse();
  MiaClasse.ClasseInterna mcci = mc.new ClasseInterna();
  mcci.metodo();
}
-- 
Life's something u don't get out alive..
ObjectZone - 
http://space.tin.it/computer/csadun