Aflați Java pentru dezvoltarea Android Mai multe despre cursurile Interioare

Această lecție rapidă discută o serie de sfaturi pentru a lucra cu clase interioare în Java. Această lecție face parte dintr-o serie continuă de tutoriale pentru dezvoltatorii care învață Java pentru a dezvolta aplicații Android.

Ce sunt clasele interioare (anonime)?

În Java, clasele pot fi imbricate între ele pentru a organiza datele și funcționalitatea în mod ordonat. Clasele interioare anonime sunt în esență stenograma dezvoltatorului, permițând dezvoltatorului să creeze, să definească și să utilizeze un obiect particularizat într-un singur pas. Clasele interioare anonime sunt utilizate frecvent în Android pentru a defini utilizatorii de comenzi pentru control, pentru a defini și a lansa fire noi și pentru a crea și a readuce obiecte personalizate în metode, fără a fi aglomerat codul cu setări inutile.

Pentru o discuție aprofundată a claselor imbricate și a celor interioare, inclusiv clase de anonime, vedeți tutorialul nostru, numit Learn Java for Android Development: Classes Inner

Accesarea variabilelor externe cu cuvântul cheie final

Uneori doriți să accesați informațiile disponibile în afara clasei interioare. Luați în considerare următorul exemplu. Aveți un ecran cu două comenzi: un Buton și un TextView. De fiecare dată când utilizatorul face clic pe butonul de comandă, controlul TextView este actualizat cu ora curentă. În cadrul clasei de activitate asociate acestui aspect, tu ar putea implementați această funcție după cum urmează:

 Butonul myButton = (butonul) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Vizualizare v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); = (TextView) findViewById (R.id.TextViewToShow); myTextview.setText ("Apasat la" + strWhen);); 

Codul de mai sus va funcționa și se va comporta conform așteptărilor. Cu toate acestea, să presupunem că ați vrut cu adevărat să declarați controlul TextView în afara clasei interioare și să îl utilizați și în alte scopuri. Poate că ați încerca să faceți acest lucru în schimb:

 TextView myTextView = (TextView) findViewById (R.id.TextViewToShow); Butonul myButton = (butonul) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (noul View.OnClickListener () public void onClick (Vizualizare v) SimpleDateFormat formatter = nou SimpleDateFormat ("h: mm: ss a") String strWhen = formatter.format (new Date); setText ("Apăsat la" + strWhen);); 

Din păcate, acest lucru nu se va compila. În schimb, veți obține eroarea de compilare "Nu mă pot referi la o variabilă non-finală myTextview într-o clasă interioară definită printr-o metodă diferită". Așa cum sugerează eroarea, ceea ce trebuie să faceți este să faceți ca variabila TextView să fie finală, astfel încât să fie accesibilă în cadrul metodei onClick () din clasa interioară:

 definitiv TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Butonul myButton = (butonul) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (noul View.OnClickListener () public void onClick (Vizualizare v) SimpleDateFormat formatter = nou SimpleDateFormat ("h: mm: ss a") String strWhen = formatter.format (new Date); setText ("Apăsat la" + strWhen);); 

Acest cod va fi într-adevăr compilat și executat conform așteptărilor.

Lucrul cu variabilele finale în Java

Prin transformarea finală a variabilei TextView în exemplul anterior, l-ați pus la dispoziția clasei interioare anonime (sau a oricărei clase interioare definite în domeniul său de aplicare, de pildă). Iată câteva alte lucruri de știut despre variabilele finale:

  • Nu puteți modifica valoarea (r-valoare) a unei variabile finale. De exemplu, dacă ați încercat să atribuiți variabila myTextview unui alt control în cadrul metodei onClick () a clasei interioare, ați obține eroarea de compilare "Variația locală finală myTextview nu poate fi atribuită, deoarece este definită într-un tip închis. “
  • Puteți apela metodele unei variabile finale, cu condiția să aveți acces. Aceasta este ceea ce ne permite să efectuăm apelul la metoda setText () a TextView. Acest lucru nu modifică valoarea variabilei myTextview, ci doar modifică ceea ce este afișat pe ecran - o diferență subtilă dar importantă. (Motivul pentru aceasta este pur și simplu că referința la obiect nu se poate schimba, dar obiectul însăși se poate schimba prin metodele sale.)
  • Valoarea unei variabile finale nu trebuie să fie cunoscută la momentul compilării, în timp ce o variabilă statică este cunoscută la momentul compilării.
  • Cuvântul cheie final este adesea asociat cu variabila statică (un câmp sau o variabilă legată de toate instanțele unei clase, în loc de o singură instanță) pentru a crea o constantă pentru a fi utilizată în aplicația dvs., la fel ca în: public statică finală String DEBUG_TAG, folosit pentru logging LogCat în întreaga activitate.

Clasele Interioare și variabila "Aceasta"

În Java, puteți utiliza funcția specială acest trimitere la referință la instanța specifică a unui obiect. Deci, ce se întâmplă atunci când aveți o clasă cu o clasă interioară sau, de altfel, o clasă anonimă interioară? Ei bine, clasa interioară poate accesa această specialitate a clasei închise și are o referință proprie. Pentru a accesa această instanță pentru clasa interioară, pur și simplu utilizați această sintaxă. Pentru a accesa această instanță a clasei de închidere, trebuie să faceți clic pe numele clasei închise, apoi pe un punct, apoi pe acesta. De exemplu:

 MyEnclosingClass.this 

Aruncați o privire la implementarea completă a clasei interioare anonime, așa cum sa discutat mai sus, în contextul integral al clasei sale închise, numită aici ClassChaosActivity:

 pachet com.androidbook.classchaos; import java.text.SimpleDateFormat; import java.util.Date; importă android.app.Activity; import android.os.Bundle; import șiroid.util.Log; import șiroid.view.View; import șiroid.widget.Button; import șiroid.widget.TextView; clasa publica ClassChaosActivity se extinde Activitatea String final public static DEBUG_TAG = "MyLoggingTag"; / ** Chemată când se creează prima activitate. * / @Override publică void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); definitiv TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Butonul myButton = (butonul) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (noul View.OnClickListener () public void onClick (Vizualizare v) SimpleDateFormat formatter = nou SimpleDateFormat ("h: mm: ss a") String strWhen = formatter.format (new Date); setText ("Apăsat la" + strWhen); Log.v (DEBUG_TAG, "acest nume de clasă:" + this.getClass () getName ()); getClass () getInterfaces () [0] .getName ()); Log.v (DEBUG_TAG, "acest nume de clasă închis:" + this.getClass () getEnclosingClass , "aceasta este o clasă anonimă" + this.getClass () esteAnonymousClass ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Denumirea clasei:" + ClassChaosActivity.this.getClass () getName ()); v (DEBUG_TAG, "ClassChaosActivity.this este o clasă anonimă" + ClassChaosActivity.this (DEBUG_TAG, "ClassChaosActivity.this este o clasă anonimă") + ClassChaosActivity.this.getClass () .getClass () esteAnonymousClass ()););  

Ieșirea jurnalului pentru clic pe buton continuă după cum urmează:

 10-24 18: 18: 53.075: VERBOSE / MyLoggingTag (751): această clasă nume: com.androidbook.classchaos.ClassChaosActivity $ 1 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag .view.View $ OnClickListener 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): acest nume de clasă închis: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): aceasta este clasa anonimă? true 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Numele clasei: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Super Numele clasei: android.app.Activity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.This este o clasă anonimă? fals 

După cum puteți vedea, acest cuvânt cheie se referă singură la clasa "cea mai apropiată" - clasa interioară. Deși clasa interioară este anonimă, Java îi dă un număr de $ 1 pentru a urmări acest lucru. Deși nu este util dezvoltatorilor per se, acest lucru arată că clasa anonimă internă este tratată ca orice altă clasă internă. Între timp, accesăm instanța de clasă care se închide folosind sintaxa ClassChaosActivity.this.

Concluzie

În această lecție rapidă ați învățat câteva sfaturi pentru a vă ajuta să utilizați clase interioare și clase interioare anonime cu mai multă îndemânare. Ați învățat că clasele interioare pot accesa variabilele declarate în afara domeniului lor de aplicare, cu condiția ca variabilele să fie marcate ca fiind finale și, prin urmare, neschimbate. De asemenea, ați aflat despre sintaxa specială legată de acest cuvânt cheie atunci când vine vorba de accesarea datelor de instanță de clasă interioară,.

despre autori

Dezvoltatorii mobili Lauren Darcey și Shane Conder au coautorizat mai multe cărți despre dezvoltarea Android: o carte de programare în profunzime intitulată Dezvoltarea aplicațiilor fără fir Android și Sams TeachYourself Dezvoltarea de aplicații Android în 24 de ore. Când nu scriu, își petrec timpul dezvoltând software-ul mobil la compania lor și oferind servicii de consultanță. Acestea pot fi obținute prin e-mail la androidwirelessdev@[email protected], prin intermediul blogului lor la androidbook.blogspot.com, și pe Twitter @ androidwireless.

Aveți nevoie de mai mult ajutor pentru scrierea aplicațiilor Android? Consultați cele mai recente cărți și resurse!

   

Cod