Cette petite leçon traite de plusieurs astuces pour travailler avec des classes internes en Java. Cette leçon fait partie d'une série de didacticiels en cours destinés aux développeurs apprenant Java afin de développer des applications Android..
En Java, les classes peuvent être imbriquées les unes dans les autres afin d'organiser les données et les fonctionnalités de manière ordonnée. Les classes internes anonymes sont un raccourci de développeur, permettant au développeur de créer, définir et utiliser un objet personnalisé en une seule fois. Les classes internes anonymes sont fréquemment utilisées dans Android pour définir des gestionnaires de contrôles, définir et lancer de nouveaux threads, et créer et renvoyer des objets personnalisés dans des méthodes sans encombrer le code avec une configuration inutile..
Pour plus d'informations sur les classes imbriquées et internes, y compris les classes internes anonymes, consultez notre didacticiel intitulé Learn Java for Android Development: Inner Classes.
Parfois, vous souhaitez accéder à des informations disponibles en dehors de la classe interne. Prenons l'exemple suivant. Vous avez un écran avec deux contrôles: un bouton et un TextView. Chaque fois que l'utilisateur clique sur le contrôle Button, le contrôle TextView est mis à jour avec l'heure actuelle. Dans la classe d’activité associée à cette mise en page, vous pourrait implémenter cette fonctionnalité comme suit:
Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () vide public onClick (Afficher v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); myTextview.setText ("Cliquez sur" + strWhen););
Le code ci-dessus s'exécutera et se comportera comme prévu. Cependant, supposons que vous vouliez vraiment déclarer le contrôle TextView en dehors de la classe interne et l'utiliser également à d'autres fins. Peut-être voudriez-vous essayer de faire cela à la place:
TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Afficher v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Cliqué à" + strWhen););
Malheureusement, cela ne compilera pas. Au lieu de cela, vous obtiendrez l'erreur de compilation «Impossible de faire référence à une variable non finale myTextview à l'intérieur d'une classe interne définie dans une méthode différente». Comme le suggère l'erreur, il suffit de rendre la variable TextView finale, de sorte qu'elle soit accessible dans la méthode onClick () de la classe interne:
final TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Afficher v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Cliqué à" + strWhen););
Ce code sera en effet compilé et exécuté comme prévu.
En rendant la variable TextView finale dans l'exemple précédent, vous l'avez mise à la disposition de la classe interne anonyme (ou de toute classe interne définie dans son étendue, d'ailleurs). Voici quelques autres choses à savoir sur les variables finales:
En Java, vous pouvez utiliser le spécial ce référence pour faire référence à l'instance spécifique d'un objet. Alors que se passe-t-il lorsque vous avez une classe avec une classe interne ou, d'ailleurs, une classe interne anonyme? Eh bien, la classe interne peut accéder à l'instance spéciale this de la classe englobante et possède également cette référence. Pour accéder à cette instance pour la classe interne, utilisez simplement la syntaxe this. Pour accéder à cette instance de la classe englobante, vous devez ajouter le nom de la classe englobante, puis un point, puis ceci. Par exemple:
MyEnclosingClass.this
Regardez l'implémentation complète de la classe interne anonyme, comme indiqué ci-dessus, dans le contexte complet de sa classe englobante, appelée ici ClassChaosActivity:
package com.androidbook.classchaos; importer java.text.SimpleDateFormat; importer java.util.Date; importer android.app.Activity; importer android.os.Bundle; importer android.util.Log; importer android.view.View; importer android.widget.Button; importer android.widget.TextView; Classe publique ClassChaosActivity. Activity public statique final String DEBUG_TAG = "MyLoggingTag"; / ** Appelé lors de la création de l'activité. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); final TextView myTextview = (TextView) findViewById (R.id.TextViewToShow); Button myButton = (Button) findViewById (R.id.ButtonToClick); myButton.setOnClickListener (new View.OnClickListener () public void onClick (Afficher v) SimpleDateFormat formatter = new SimpleDateFormat ("h: mm: ss a"); String strWhen = formatter.format (new Date ()); myTextview. setText ("Cliquez sur" + strWhen); Log.v (DEBUG_TAG, "nom de cette classe:" + this.getClass (). getName ()); Log.v (DEBUG_TAG, "cette interface étendue est nommée:" + ceci. getClass (). getInterfaces () [0] .getName ()) Log.v (DEBUG_TAG, "this Nom de la classe englobante:" + this.getClass (). getEnclosingClass (). getName ()); Log.v (DEBUG_TAG , "Ceci est une classe anonyme?" + this.getClass (). isAnonymousClass ()); Log.v (DEBUG_TAG, "ClassChaosActivity.this Nom de classe:" + ClassChaosActivity.this.getClass (). getName ()); Log. v (DEBUG_TAG, "ClassChaosActivity.this Nom de la super classe:" + ClassChaosActivity.this.getClass (). getSuperclass (). getName ()); Log.v (DEBUG_TAG, "ClassChaosActivity.th est une classe anonyme?" + ClassChaosActivity.th est .getClass (). isAnonymousClass ()););
La sortie du journal pour le clic du bouton se déroule comme suit:
10-24 18: 18: 53.075: VERBOSE / MyLoggingTag (751): ce nom de classe: com.androidbook.classchaos.ClassChaosActivity $ 1 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): cela étend l'interface nommée: android .view.View $ OnClickListener 10-24 18: 18: 53.085: VERBOSE / MyLoggingTag (751): ce nom de classe englobant: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): C'est une classe anonyme? true 10-24 18: 18: 53.095: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Nom de classe: com.androidbook.classchaos.ClassChaosActivity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Super Nom de classe: android.app.Activity 10-24 18: 18: 53.105: VERBOSE / MyLoggingTag (751): ClassChaosActivity.this Est une classe anonyme? faux
Comme vous pouvez le constater, le mot-clé this lui-même fait référence à la classe la plus proche, la classe interne. Bien que la classe interne soit anonyme, Java lui attribue un numéro ClassChaosActivity $ 1 pour en assurer le suivi. Bien que cela ne soit pas utile aux développeurs, cela montre que la classe interne anonyme est traitée comme toute autre classe en interne. En attendant, nous accédons à l’instance de classe englobante à l’aide de la syntaxe ClassChaosActivity.this.
Dans cette leçon rapide, vous avez appris plusieurs astuces pour vous aider à utiliser plus habilement les classes internes et les classes internes anonymes. Vous avez appris que les classes internes peuvent accéder aux variables déclarées en dehors de leur portée, à condition que les variables soient marquées comme finales et donc non modifiables. Vous avez également appris la syntaxe spéciale liée au mot-clé this lorsqu’il s’agit d’accéder aux données d’instance de classe interne, ainsi que ses données d’instance de classe.
Les développeurs mobiles Lauren Darcey et Shane Conder ont co-écrit plusieurs livres sur le développement Android: un livre de programmation en profondeur intitulé Développement d'applications sans fil Android et Sams TeachYourself Développement d'applications Android en 24 heures. Lorsqu'ils n'écrivent pas, ils passent leur temps à développer des logiciels mobiles dans leur entreprise et à fournir des services de conseil. Vous pouvez les contacter par courrier électronique à l'adresse [email protected], via leur blog à l'adresse androidbook.blogspot.com et sur Twitter @androidwireless..