Deze korte les bespreekt een aantal tips voor het werken met innerlijke klassen op Java. Deze les maakt deel uit van een doorlopende reeks tutorials voor ontwikkelaars die Java leren om Android-applicaties te ontwikkelen.
In Java kunnen klassen in elkaar worden genest om gegevens en functionaliteit ordelijk te organiseren. Anonieme binnenklassen zijn in feite ontwikkelaars stenografisch, waardoor de ontwikkelaar in één keer een aangepast object kan maken, definiëren en gebruiken. Anonieme binnenklassen worden vaak gebruikt in Android om handlers voor besturingselementen te definiëren, nieuwe threads te definiëren en te starten en aangepaste objecten te maken en terug te sturen in methoden zonder rommelcode met onnodige instellingen.
Voor een grondige bespreking van geneste en innerlijke klassen, inclusief anonieme innerlijke klassen, zie onze tutorial Learn Java voor Android-ontwikkeling: Innerlijke klassen
Soms wil je toegang krijgen tot informatie die beschikbaar is buiten de innerlijke klasse. Bekijk het volgende voorbeeld. Je hebt een scherm met twee besturingselementen: een knop en een tekstweergave. Telkens wanneer de gebruiker op de knopbesturing klikt, wordt het TextView-besturingselement bijgewerkt met de huidige tijd. In de klasse Activiteit die aan deze lay-out is gekoppeld, jij kon implementeer deze functionaliteit als volgt:
Knop myButton = (Knop) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (nieuwe View.OnClickListener () public void onClick (View 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););
De bovenstaande code wordt uitgevoerd en werkt zoals verwacht. Laten we echter zeggen dat u het TextView-besturingselement echt buiten de innerlijke klasse wilde verklaren en het ook voor andere doeleinden wilt gebruiken. Misschien zou je dit in plaats daarvan proberen te doen:
TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Knop myButton = (Knop) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (View v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Klikte op" + strWhen););
Helaas zal dit niet compileren. In plaats daarvan krijgt u de compileerfout "Kan niet verwijzen naar een niet-definitieve variabele myTextview binnen een innerlijke klasse die op een andere methode is gedefinieerd". Zoals de fout suggereert, moet u de TextView-variabele definitief maken, zodat deze toegankelijk is binnen de onClick () -methode van de inner class:
final TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Knop myButton = (Knop) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (View v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Klikte op" + strWhen););
Deze code zal inderdaad worden gecompileerd en uitgevoerd zoals verwacht.
Door de TextView-variabele definitief te maken in het vorige voorbeeld, hebt u deze beschikbaar gemaakt voor de anonieme innerlijke klasse (of elke binnenklasse die binnen de scope ervan is gedefinieerd). Hier zijn nog enkele andere dingen die u moet weten over definitieve variabelen:
In Java kun je de special gebruiken deze verwijzing om te verwijzen naar het specifieke exemplaar van een object. Dus wat gebeurt er als je een klas hebt met een innerlijke klasse, of, wat dat betreft, een anonieme innerlijke klasse? Welnu, de innerlijke klasse heeft toegang tot de speciale instantie van de omsluitende klasse, en deze heeft ook een eigen referentie. Gebruik de syntaxis om toegang te krijgen tot deze instantie voor de binnenklasse. Om toegang te krijgen tot de klasse van de omsluitende klasse, moet je eerst de naam van de insluitende klasse, dan een punt, dan dit. Bijvoorbeeld:
MyEnclosingClass.this
Bekijk de volledige implementatie van de anonieme innerlijke klasse, zoals hierboven besproken, in de volledige context van de omsluitende klasse, hier ClassChaosActivity genaamd:
pakket com.androidbook.classchaos; importeer java.text.SimpleDateFormat; importeer java.util.Date; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; importeer android.widget.Button; import android.widget.TextView; public class ClassChaosActivity breidt activiteit uit public static final String DEBUG_TAG = "MyLoggingTag"; /** Opgeroepen wanneer de activiteit voor het eerst is gemaakt. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); final TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Knop myButton = (Knop) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (View v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Clicked at" + strWhen); Log.v (DEBUG_TAG, "this Class name:" + this.getClass (). getName ()); Log.v (DEBUG_TAG, "this extends interface named:" + this. getClass (). getInterfaces () [0] .getName ()); Log.v (DEBUG_TAG, "this Enclosing class name:" + this.getClass (). getEnclosingClass (). getName ()); Log.v (DEBUG_TAG , "this Is anonymous class?" + this.getClass (). isAnonymousClass ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Class name:" + ClassChaosActivity.this.getClass (). getName ()); Log. v (DEBUG_TAG, "ClassChaosActivity.this Super Class name:" + ClassChaosActivity.this.getClass (). getSuperclass (). getName ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Is anonymous class?" + ClassChaosActivity.this .getClass (). isAnonymousClass ()););
De loguitvoer voor de knopklik verloopt als volgt:
10-24 18: 18: 53.075: VERBOSE / MyLoggingTag (751): deze klassenaam: com.androidbook.classchaos.ClassChaosActivity $ 1 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): dit breidt de interface met de naam: android uit .view.View $ OnClickListener 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): deze insluitende klassenaam: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): dit is een anonieme les? true 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Class name: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Super Klasse naam: android.app.Activity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Is anonymous class? vals
Zoals je kunt zien, verwijst het alleen dit sleutelwoord naar de 'dichtstbijzijnde' klas, de innerlijke klasse. Hoewel de binnenklasse anoniem is, geeft Java het een nummer ClassChaosActivity $ 1 om het bij te houden. Hoewel dit op zich niet handig is voor ontwikkelaars, toont dit aan dat de anonieme innerlijke klasse intern wordt behandeld als elke andere klas. Ondertussen hebben we toegang tot de insluitende klasseninstantie met behulp van de classChaosActivity.deze syntaxis.
In deze korte les heb je verschillende tips geleerd om je te helpen om innerlijk en anonieme lessen beter te gebruiken. U hebt geleerd dat interne klassen toegang hebben tot variabelen die buiten hun bereik zijn verklaard, op voorwaarde dat de variabelen als definitief en daarom onveranderlijk zijn gemarkeerd. U hebt ook geleerd over de speciale syntaxis gerelateerd aan dit sleutelwoord als het gaat om toegang krijgen tot interne klasse-instantie-gegevens evenals de omsluitende klasseninstantie-gegevens.
Mobiele ontwikkelaars Lauren Darcey en Shane Conder hebben samen meerdere boeken geschreven over Android-ontwikkeling: een diepgaand programmeerboek getiteld Android Wireless Application Development en Sams TeachYourself Android Application Development binnen 24 uur. Wanneer ze niet schrijven, besteden ze hun tijd aan het ontwikkelen van mobiele software bij hun bedrijf en het leveren van consultingservices. Ze zijn te bereiken via e-mail naar [email protected], via hun blog op androidbook.blogspot.com, en op Twitter @androidwireless.