Denne raske leksjonen diskuterer en rekke tips for å jobbe med indre klasser i Java. Denne leksjonen er en del av en kontinuerlig serie av opplæringsprogrammer for utviklere som lærer Java for å utvikle Android-applikasjoner.
I Java kan klasser være nestet i hverandre for å organisere data og funksjonalitet på en ordnet måte. Anonyme indre klasser er i utgangspunktet utvikler stenografi, slik at utvikleren kan lage, definere og bruke et tilpasset objekt på en gang. Anonyme indre klasser brukes ofte i Android for å definere håndtere for kontroller, definere og starte nye tråder, og opprette og returnere egendefinerte objekter i metoder uten roteringskode med unødvendig oppsett.
For en grundig diskusjon om nestede og indre klasser, inkludert anonyme indre klasser, se vår veiledning kalt Learn Java for Android Development: Inner Classes
Noen ganger vil du få tilgang til informasjon tilgjengelig utenfor den indre klassen. Vurder følgende eksempel. Du har en skjerm med to kontroller: en knapp og en tekstvisning. Hver gang brukeren klikker på knappekontrollen, blir TextView-kontrollen oppdatert med gjeldende tid. Innen Aktivitetsklassen knyttet til dette oppsettet, er du kunne implementer denne funksjonaliteten som følger:
Knapp myButton = (Button) findViewById (R.id.ButtonToClick); MyButton.setOnClickListener (new View.OnClickListener () public void onClick (Vis v) SimpleDateFormat formatter = ny SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (ny dato ()); TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); myTextview.setText ("Clicked at" + strWhen););
Ovennevnte kode vil kjøre og oppføre seg som forventet. La oss imidlertid si at du virkelig ville deklarere TextView-kontrollen utenfor den indre klassen og bruke den til andre formål også. Kanskje du ville prøve å gjøre dette i stedet:
TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Knapp myButton = (Button) findViewById (R.id.ButtonToClick); MyButton.setOnClickListener (new View.OnClickListener () public void onClick (Vis v) SimpleDateFormat formatter = ny SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (ny dato ()); myTextview. setText ("Clicked at" + strWhen););
Dessverre vil dette ikke kompilere. I stedet får du kompileringsfeilen "Kan ikke referere til en ikke-endelig variabel myTextview i en indre klasse definert i en annen metode". Som feilen antyder, er det nødvendig å gjøre TextView-variabelen endelig, slik at den er tilgjengelig i den indre klassens onClick () -metode:
siste tekstvisning myTextview = (TextView) findViewById (R.id.TextViewToShow); Knapp myButton = (Button) findViewById (R.id.ButtonToClick); MyButton.setOnClickListener (new View.OnClickListener () public void onClick (Vis v) SimpleDateFormat formatter = ny SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (ny dato ()); myTextview. setText ("Clicked at" + strWhen););
Denne koden vil faktisk kompilere og løpe som forventet.
Ved å gjøre TextView-variabelen endelig i det forrige eksempelet, har du gjort det tilgjengelig for den anonyme indre klassen (eller en hvilken som helst indre klasse som er definert innenfor sitt omfang, for den saks skyld). Her er noen andre ting å vite om sluttvariabler:
I Java kan du bruke den spesielle dette referanse for å referere til den konkrete forekomsten av et objekt. Så hva skjer når du har en klasse med en indre klasse, eller, for den saks skyld, en anonym indre klasse? Vel, den indre klassen kan få tilgang til den spesielle denne forekomsten av den vedlagte klassen, og den har også denne referansen sin. For å få tilgang til denne forekomsten for den indre klassen, bruk bare denne syntaksen. For å få tilgang til denne forekomsten av den vedlagte klassen må du takke navnet på den vedlagte klassen, deretter en prikk, deretter dette. For eksempel:
MyEnclosingClass.this
Ta en titt på den fullstendige implementeringen av den anonyme indre klassen, som diskutert ovenfor, i full kontekst av sin omsluttende klasse, her kalt ClassChaosActivity:
pakke com.androidbook.classchaos; importer java.text.SimpleDateFormat; importer java.util.Date; importer android.app.Activity; importere android.os.Bundle; importer android.util.Log; importer android.view.View; importer android.widget.Button; importer android.widget.TextView; offentlig klasse ClassChaosActivity utvider Aktivitet offentlig statisk endelig streng DEBUG_TAG = "MyLoggingTag"; / ** Kalt når aktiviteten er først opprettet. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); siste tekstvisning myTextview = (TextView) findViewById (R.id.TextViewToShow); Knapp myButton = (Button) findViewById (R.id.ButtonToClick); MyButton.setOnClickListener (new View.OnClickListener () public void onClick (Vis v) SimpleDateFormat formatter = ny SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (ny dato ()); myTextview. setTxt ("Clicked at" + strWhen); Log.v (DEBUG_TAG, "dette klassenavnet:" + this.getClass (). getName ()); Log.v (DEBUG_TAG, "dette utvider grensesnittet heter:" + dette. GetClass (). getInterfaces () [0] .getName ()); Log.v (DEBUG_TAG, "dette Vedlegg klassenavn:" + this.getClass (). getEnclosingClass (). getName ()); Log.v (DEBUG_TAG , "Dette er anonym klasse?" + this.getClass () .AnonymousClass ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Klassenavn:" + ClassChaosActivity.this.getClass (). getName ()); Logg. v (DEBUG_TAG, "ClassChaosActivity.this Super Class navn:" + ClassChaosActivity.this.getClass (). getSuperclass (). getName ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Er anonym klasse?" + ClassChaosActivity.this .getClass (). isAnonymousClass ()););
Loggutgangen for knappeklikk fortsetter som følger:
10-24 18: 18: 53.075: VERBOSE / MyLoggingTag (751): dette klassenavnet: com.androidbook.classchaos.ClassChaosActivity $ 1 10-24 18: 18: 53,085: VERBOSE / MyLoggingTag (751): dette utvider grensesnittet heter: android .view.View $ OnClickListener 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): dette omsluttende klassenavn: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): dette er anonym klasse? True 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Klassenavn: com.androidbook.classchaos.ClassChaosAktivitet 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Super Klassenavn: android.app.Aktivitet 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Er anonym klasse? falsk
Som du kan se, refererer dette søkeordet til den "nærmeste" klassen - den indre klassen. Selv om den indre klassen er anonym, gir Java det et antall ClassChaosActivity $ 1 for å holde rede på det. Selv om det ikke er nyttig for utviklere per se, viser dette at den anonyme indre klassen behandles som en annen klasse internt. I mellomtiden får vi tilgang til det vedlagte klassetilfellet ved hjelp av ClassChaosActivity.this syntaks.
I denne raske leksjonen har du lært flere tips for å hjelpe deg med å bruke indre klasser og anonyme indre klasser mer dyktig. Du lærte at indre klasser kan få tilgang til variabler deklarert utenfor deres omfang, forutsatt at variablene er merket som endelige og derfor uforanderlige. Du har også lært om den spesielle syntaksen som er relatert til dette søkeordet når det gjelder tilgang til indre klasse-forekomstdata, samt omsluttelse av klasseeksemplardata.
Mobilutviklere Lauren Darcey og Shane Conder har medforfatter flere bøker om Android-utvikling: en grundig programmeringsbok med tittel Android Wireless Application Development og Sams TeachYourself Android Application Development i 24 timer. Når de ikke skriver, bruker de sin tid på å utvikle mobil programvare hos deres firma og tilby konsulenttjenester. De kan nås via e-post til [email protected], via bloggen deres på androidbook.blogspot.com, og på Twitter @androidwireless.