Aflați Java pentru dezvoltarea Android clase interioare

În acest tutorial, vă veți familiariza cu conceptul de clase interioare în Java - acele clase a căror scop și definiție sunt cuprinse într-o altă clasă. Veți învăța, de asemenea, despre clasele interioare anonime, care sunt utilizate destul de frecvent când se dezvoltă cu SDK-ul Android.

Aplicațiile Android sunt scrise în Java, un limbaj de programare orientat pe obiecte. În acest tutorial, veți învăța despre clasele interioare, când și de ce să le folosiți și cum funcționează. Veți învăța, de asemenea, cum să creați dinamic obiecte noi folosind clase interioare anonime.

Ce ai nevoie

Din punct de vedere tehnic, nu aveți nevoie de niciun fel de instrumente pentru a finaliza acest tutorial, dar cu siguranță veți avea nevoie de ele pentru a dezvolta aplicații Android.

Pentru a dezvolta aplicații Android (sau orice aplicații Java, de pildă), aveți nevoie de un mediu de dezvoltare pentru a scrie și a construi aplicații. Eclipse este un mediu de dezvoltare foarte popular (IDE) pentru Java și IDE preferat pentru dezvoltarea Android. Este disponibil gratuit pentru sistemele de operare Windows, Mac și Linux.

Pentru instrucțiuni complete despre cum să instalați Eclipse (inclusiv versiunile acceptate) și SDK-ul Android, consultați site-ul Web pentru dezvoltatorii Android.

Ce este o clasă interioară?

Cele mai multe clase din Java sunt clase de nivel superior. Aceste clase și obiectele pe care le definesc sunt independente. De asemenea, puteți crea clase imbricate pentru a încapsula în mod clar și a defini obiecte subordonate care contează numai în contextul clasei exterioare. Clasele investite sunt numite clase interioare.

Clasele interioare pot avea toate caracteristicile unei clase obișnuite, însă domeniul lor de aplicare este limitat. Clasele interioare au un alt beneficiu: au acces deplin la clasa în care sunt imbricate - această caracteristică face clasele interioare perfecte pentru implementarea funcțiilor adaptorului, cum ar fi iteratorii.

Iată un exemplu de clasă de nivel superior cu două clase interioare:

 public User class // Câmpuri de utilizator, inclusiv variabile de tip LoginInfo și UserPreferences // Metode diferite de utilizatori de clasă LoginInfo // Domenii de conectare // Metode de conectare / deconectare // Pot accesa câmpurile / metodele de utilizator Clasa Preferințe // User câmpuri de preferință // Metode de obținere / setare a preferințelor // Metoda de resetare a preferințelor // Poate accesa câmpurile / metodele utilizatorilor 

În acest exemplu, clasa User are două clase interioare: LoginInfo și Preferințe. În timp ce toate datele și funcționalitatea legate de utilizator ar putea fi definite în clasa Utilizator, utilizarea claselor interioare pentru compartimentarea funcționalității poate face mai ușor citirea și menținerea codului. Clasele interioare LoginInfo și Preferences au, de asemenea, acces la câmpurile protejate / private și la metodele disponibile în cadrul clasei User, pe care altfel nu le-ar putea avea din cauza securității, dacă au fost definite ca fiind clase de sine stătătoare.

Este important să ne amintim, totuși, că clasele interioare există într-adevăr pentru a ajuta organizatorul să organizeze codul; compilatorul tratează clasele interioare la fel ca orice altă clasă, cu excepția faptului că clasele interioare au un domeniu limitat și, prin urmare, sunt legate de clasa în care sunt definite. A spus într-un alt mod, nu ați putea să utilizați sau să instanțiați clasele LoginInfo sau Preferințe, cu excepția unei instanțe a clasei User, dar clasele interioare ar putea accesa toate câmpurile sau metodele disponibile în clasa exterioară User, după cum este necesar.

Utilizarea de clase încrucișate

O utilizare specială pentru clasele imbricate este clasa imbricată statică. O clasă internă statică definește un comportament care nu este legat de o anumită instanță de obiect, dar se aplică în toate situațiile. De exemplu, am putea adăuga oa treia clasă imbricată, de această dată statică, la clasa User pentru a controla funcționalitățile legate de server:

 public class User // Câmpuri de utilizator, inclusiv variabile de tip LoginInfo și UserPreferences // Metode diferite de utilizatori clasa LoginInfo  clasa statică publică ServerInfo  // Informațiile despre server se aplică tuturor instanțelor utilizatorului 

Deoarece este public, această clasă imbricată statică poate fi instanțiată utilizând următoarea declarație nouă:

 User.ServerInfo sInfo = nou utilizator.ServerInfo (); 

Clasa exterioară nu trebuie să fie instanțiată pentru a efectua această instanțiere, deci folosirea numelui clasei. Astfel, o clasă imbricată statică, spre deosebire de o clasă imbricată non-statică (cunoscută și ca clasă interioară), nu are acces la membrii clasei exterioare - ei nu pot fi chiar instanțiați.

Puterea claselor interne anonime

Android folosește clase interioare anonime pentru un efect grozav. Clasele interioare anonime sunt în esență stenografi pentru dezvoltatori, permițând dezvoltatorului să creeze, să definească și să utilizeze un obiect personalizat într-o singură "linie". Probabil ați văzut exemple de utilizare a clasei interioare anonime în exemplul de cod și nici nu l-ați realizat.
Pentru a crea o clasă anonimă interioară, oferiți doar partea dreaptă a definiției. Începeți cu noul cuvânt cheie, urmat de clasa sau interfața pe care doriți să o extindeți sau să o implementați, urmată de definiția clasei. Aceasta va crea clasa și o va returna ca valoare pe care o puteți folosi pentru a apela o metodă.
Când folosim o clasă anonimă interioară, obiectul creat nu primește un nume (astfel, termenul anonim). Efectul secundar, desigur, este că obiectul este folosit folosit o singură dată. De exemplu, este obișnuit să folosiți o clasă anonimă interioară pentru a construi o versiune personalizată a unui obiect ca valoare de retur. De exemplu, aici extindem clasa Truck (presupunând că este definită în altă parte și are un câmp numit mpg și două metode, start () și stop ():

 Camion getTruck () retur nou camion () int mpg = 3; void start () / * începe implementarea * / void stop () / * stop implementation * /;  

Acum, să aruncăm o privire asupra exemplelor practice ale claselor anonime folosite în Android.

Folosind o clasă anonimă interioară pentru a defini un ascultător

Dezvoltatorii de aplicații Android folosesc adesea clase interne anonime pentru a defini ascultători specializați, care înregistrează apeluri de apel pentru comportamente specifice atunci când apare un eveniment. De exemplu, pentru a asculta clicurile pe un control de vizualizare, dezvoltatorul trebuie să apeleze metoda setOnClickListener (), care ia un singur parametru: un obiect View.OnClickListener.
Dezvoltatorii utilizează în mod obișnuit tehnica anonimă de clasă interioară pentru a crea, defini și utiliza View.OnClickListener personalizat, după cum urmează:

 Buton aButton = (buton) findViewById (R.id.MyButton); aButton.setOnClickListener (noul View.OnClickListener () public void onClick (Vezi v) // Utilizatorul mi-a dat click pe butonul meu, face ceva aici!); 

Folosind o clasă anonimă interioară pentru a începe un subiect

Să ne uităm la un alt exemplu. Este destul de comun să definiți o nouă clasă Thread, să furnizați implementarea metodei run () și să începeți acel thread, toate într-un singur pas:

 un nou fișier () public void run () doWorkHere ();  .start(); 

Utilizând o clasă interioară numită

Utilizarea claselor anonime pentru ascultători în Android este atât de comun încât este practic oa doua natură să facă acest lucru. De ce, nu ai vrea să le folosești? Să răspundem la aceasta printr-un exemplu ipotetic.
Să presupunem că aveți un ecran care are 100 de butoane pe el (am spus ipotetic, nu?). Acum, să spunem că fiecare buton, atunci când este apăsat, face exact același lucru. În acest caz, vom asculta doar pentru clicuri și Toast textul din obiectul View a trecut (textul afișat pe butonul care a fost apăsat):
Iată codul pseudo pentru a face acest lucru:

 Butoane [] butoane = getAllOneHundredButtonsAsArray (); pentru (Buton buton: butoane) button.setOnClickListener (new View.OnClickListener () public void onClick (Vizualizare v) showToast (v.getText ()););  

Scurt și elegant, deci ce e în neregulă cu ea? La fiecare iterație, un nou obiect OnClickListener este instanțiat. Deoarece fiecare dintre ele este exact la fel, nu există nici un motiv bun pentru a crea 100 dintre ele. În schimb, puteți crea o singură clasă, numită, clasă interioară, o instanțiați o singură dată, apoi treceți aceasta la metoda setOnClickListener (). De exemplu:

 clasa MyActivity extinde Activitatea public void myMethod () MyClickHandler handler = nou MyClickHandler (); Butoane [] butoane = getAllOneHundredButtonsAsArray (); pentru (Buton buton: butoane) button.setOnClickListener (handler);  clasa MyClickHandler implementează View.OnClickListener public void onClick (View v) showToast (((Buton) v) .getText ());  

Dacă preferați anonimatul, puteți încă să atribuiți unei clase interioare anonime unei variabile și să o utilizați astfel:

 class MyActivity extinde Activitatea public void myMethod () View.OnClickListener handler = nou View.OnClickListener () public void onClick (Vezi v) showToast ((Butonul) v) .getText ()); ; Butoane [] butoane = getAllOneHundredButtonsAsArray (); pentru (Buton buton: butoane) button.setOnClickListener (handler);  

Metoda este de până la tine, dar ține minte potențialele probleme de memorie și de performanță pe care instanțializarea unei grămezi de obiecte poate avea.

O notă privind nuanțele

Acest tutorial este menit să fie un ghid introductiv pentru clasele interioare din Java. Există considerații de stil și nuanțe atunci când se folosesc clase interioare în moduri diferite și creative. Chiar și dincolo de asta, puteți explora mai mult pentru a afla mai multe despre efectele interne și diferențele marginal de performanță care pot apărea atunci când utilizați clase imbricate în moduri diferite. Toate acestea, totuși, depășesc cu mult scopul acestui tutorial.

O notă rapidă privind terminologia

Deși am încercat să fie în concordanță cu terminologia claselor imbricate și interioare, terminologia nu este întotdeauna consecventă din diferite resurse online și offline. Următoarele sunt o listă de termeni din actuala documentație Sun / Oracle, care este la fel de bună ca și oricare dintre cele pentru a fi autoritate în Java:

  • Categoria încorporată: o clasă definită într-o altă clasă
  • Clasa statică încorporată: o clasă statică definită într-o altă clasă
  • Clasa interioară: o clasă imbricată non-statică definită într-o altă clasă
  • Clasa interioară locală: o clasă definită în cadrul unei metode
  • Clasa anonimă interioară: o clasă nesemnată definită în cadrul unei metode

Confuz? Puteți utiliza metodele java.lang.Class numite isLocalClass () și isAnonymous () clasa în clase instanțiate pentru a determina câteva din aceste proprietăți. O intrare de blog Oracle încearcă să clarifice și situația puțin, cu o diagrama plăcută a lui Venn.

Înfășurarea în sus

Limba de programare Java acceptă clase imbricate, permițând dezvoltatorului o mare flexibilitate în definirea obiectelor. Clasele interioare pot fi folosite pentru a organiza funcționalitatea de clasă sau pentru a defini comportamentele de specialitate care altfel ar necesita dezvoltatorul să expună date de clasă și funcționalități care într-adevăr nu ar trebui expuse. Clasele interioare statice pot fi folosite pentru a defini câmpurile și funcționalitatea care se aplică în toate instanțele unei clase. În cele din urmă, clasele interioare anonime oferă o stenogramă utilă pentru dezvoltatorii care doresc să creeze, să definească și să utilizeze un obiect personalizat pe rând.

Cod