Questa breve lezione discute una serie di suggerimenti per lavorare con le classi interne in Java. Questa lezione fa parte di una serie continua di tutorial per gli sviluppatori che stanno imparando Java per sviluppare applicazioni Android.
In Java, le classi possono essere annidate l'una nell'altra al fine di organizzare dati e funzionalità in modo ordinato. Le classi interne anonime sono fondamentalmente stenografia dello sviluppatore, consentendo allo sviluppatore di creare, definire e utilizzare un oggetto personalizzato tutto in una volta. Le classi interne anonime sono frequentemente utilizzate in Android per definire i gestori per i controlli, definire e lanciare nuovi thread e creare e restituire oggetti personalizzati in metodi senza codice ingombrante con impostazioni non necessarie.
Per una discussione approfondita delle classi interne e nidificate, comprese le classi interne anonime, consultare il nostro tutorial chiamato Learn Java per Android Development: Inner Classes
A volte si desidera accedere alle informazioni disponibili al di fuori della classe interna. Considera il seguente esempio. Hai una schermata con due controlli: un pulsante e una vista testo. Ogni volta che l'utente fa clic sul controllo Button, il controllo TextView viene aggiornato con l'ora corrente. All'interno della classe Attività associata a questo layout, tu poteva implementare questa funzionalità come segue:
Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Visualizza v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); myTextview.setText ("Clicked at" + strWhen););
Il codice precedente verrà eseguito e si comporterà come previsto. Tuttavia, diciamo che volevi davvero dichiarare il controllo TextView al di fuori della classe interna e usarlo anche per altri scopi. Forse dovresti provare a farlo invece:
TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Visualizza v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Clicked at" + strWhen););
Sfortunatamente, questo non verrà compilato. Invece, otterrai l'errore di compilazione "Impossibile riferirsi a una variabile non finale myTextview all'interno di una classe interna definita in un metodo diverso". Come suggerisce l'errore, ciò che devi fare è rendere definitiva la variabile TextView, in modo che sia accessibile all'interno del metodo onClick () della classe interna:
TextView finale myTextview = (TextView) findViewById (R.id.TextViewToShow); Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Visualizza v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Clicked at" + strWhen););
Questo codice verrà effettivamente compilato ed eseguito come previsto.
Rendendo definitiva la variabile TextView nell'esempio precedente, l'hai resa disponibile per la classe interna anonima (o per qualsiasi classe interna definita all'interno del suo ambito, peraltro). Ecco alcune altre cose da sapere sulle variabili finali:
In Java, puoi usare lo speciale Questo riferimento per fare riferimento all'istanza specifica di un oggetto. Quindi cosa succede quando hai una classe con una classe interiore o, per quella materia, una classe interiore anonima? Bene, la classe interna può accedere alla speciale questa istanza della classe che li contiene, e ha anche questo riferimento. Per accedere a questa istanza per la classe interna, usa semplicemente questa sintassi. Per accedere a questa istanza della classe che include, è necessario virare sul nome della classe che racchiude, quindi un punto, quindi questo. Per esempio:
MyEnclosingClass.this
Dai un'occhiata alla piena implementazione della classe interna anonima, come discusso sopra, nel contesto completo della sua classe di chiusura, qui chiamata ClassChaosActivity:
pacchetto com.androidbook.classchaos; import java.text.SimpleDateFormat; import java.util.Date; importare android.app.Activity; importare android.os.Bundle; import android.util.Log; importa android.view.View; importa android.widget.Button; import android.widget.TextView; public class ClassChaosActivity estende Activity public static final String DEBUG_TAG = "MyLoggingTag"; / ** Chiamato quando l'attività viene creata per la prima volta. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); TextView finale myTextview = (TextView) findViewById (R.id.TextViewToShow); Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Visualizza v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Clicked at" + strWhen); Log.v (DEBUG_TAG, "questo Nome classe:" + this.getClass (). getName ()); Log.v (DEBUG_TAG, "questa estende l'interfaccia denominata:" + this. getClass (). getInterfaces () [0] .getName ()); Log.v (DEBUG_TAG, "questo nome di classe Enclosing:" + this.getClass (). getEnclosingClass (). getName ()); Log.v (DEBUG_TAG , "this Is anonymous class?" + this.getClass (). isAnonymousClass ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Nome classe:" + ClassChaosActivity.this.getClass (). getName ()); Log. v (DEBUG_TAG, "ClassChaosActivity.this Super Class name:" + ClassChaosActivity.this.getClass (). getSuperclass (). getName ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this È una classe anonima?" + ClassChaosActivity.this .getClass (). isAnonymousClass ()););
L'output del registro per il clic del pulsante procede come segue:
10-24 18: 18: 53.075: VERBOSE / MyLoggingTag (751): questo Nome classe: com.androidbook.classchaos.ClassChaosActivity $ 1 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): estende l'interfaccia denominata: android .view.View $ OnClickListener 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): questo nome classe Enclosing: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): questa è una classe anonima? true 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Nome classe: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Super Nome classe: android.app.Activity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.questa classe anonima? falso
Come puoi vedere, questa parola chiave si riferisce alla classe "più vicina", la classe interiore. Sebbene la classe interna sia anonima, Java gli fornisce un numero ClassChaosActivity $ 1 per tenerne traccia. Sebbene non sia utile agli sviluppatori di per sé, ciò dimostra che la classe interna anonima è trattata internamente come qualsiasi altra classe. Nel frattempo, accediamo all'istanza della classe che include la sintassi ClassChaosActivity.this.
In questa breve lezione hai appreso diversi suggerimenti per aiutarti a usare le classi interiori e le classi interiori anonime con maggiore abilità. Hai imparato che le classi interne possono accedere a variabili dichiarate al di fuori del loro ambito, a condizione che le variabili siano contrassegnate come finali e quindi immutabili. Hai anche imparato a conoscere la sintassi speciale relativa a questa parola chiave quando si tratta di accedere ai dati delle istanze delle classi interne e ai dati delle istanze della classe che li contengono.
Gli sviluppatori mobili Lauren Darcey e Shane Conder hanno coautore diversi libri sullo sviluppo di Android: un libro di programmazione approfondito intitolato Sviluppo di applicazioni wireless Android e Sams TeachYourself Sviluppo di applicazioni Android in 24 ore. Quando non scrivono, passano il loro tempo a sviluppare software mobile presso la loro azienda ea fornire servizi di consulenza. Possono essere contattati via email a [email protected], tramite il loro blog su androidbook.blogspot.com e su Twitter @androidwireless.