t
t
t
t
t t   8) Interfaces et classes internes
tttt
t
carrea) Préface carreb) Avant-propos carre1) Introduction sur les &laqo; objets » carre2) Tout est &laqo; objet » carre3) Contrôle du flux du programme carre4) Initialization & Cleanup carre5) Cacher l'implémentation carre6) Réutiliser les classes carre7) Polymorphisme 8) Interfaces & classes internes carre9) Stockage des objets carre10) Error Handling with Exceptions carre11) Le système d’E/S de Java carre12) Identification dynamique de type carre13) Création de fenêtres & d'Applets carre14) Les &laqo; Threads » multiples carre15) Informatique distribuée carreA) Passage et retour d'objets carreB) L'Interface Java Natif (JNI) carreC) Conseils pour une programation stylée en Java carreD) Resources
Texte original t Traducteur : Jérome Quelin
t
t
///
Ce chapitre contient 6 pages
1 2 3 4 5 6
    
t t t
t t t
t
t t t
Note that light, water, thermostat, and rings all belong to the outer class GreenhouseControls, and yet the inner classes can access those fields without qualification or special permission. Also, most of the action( ) methods involve some sort of hardware control, which would most likely involve calls to non-Java code.
t Notez que light, water, thermostat et rings appartiennent tous à la classe externe GreenhouseControls, et donc les classes internes peuvent accéder à ces champs sans qualification ou permission particulière. De plus, la plupart des méthodes action() effectuent un contrôle hardware, qui implique certainement des appels à du code non-Java.
t t t
Most of the Event classes look similar, but Bell and Restart are special. Bell rings, and if it hasn’t yet rung enough times it adds a new Bell object to the event list, so it will ring again later. Notice how inner classes almost look like multiple inheritance: Bell has all the methods of Event and it also appears to have all the methods of the outer class GreenhouseControls.
t La plupart des classes Event sont similaires, mais Bell et Restart sont spéciales. Bell sonne, et si elle n'a pas sonné un nombre suffisant de fois, elle ajoute un nouvel objet Bell à la liste des événements afin de sonner à nouveau plus tard. Notez comme les classes internes semblent bénéficier de l'héritage multiple : Bell possède toutes les méthodes d'Event mais elle semble disposer également de toutes les méthodes de la classe externe GreenhouseControls.
t t t
Restart is responsible for initializing the system, so it adds all the appropriate events. Of course, a more flexible way to accomplish this is to avoid hard-coding the events and instead read them from a file. (An exercise in Chapter 11 asks you to modify this example to do just that.) Since Restart( ) is just another Event object, you can also add a Restart object within Restart.action( ) so that the system regularly restarts itself. And all you need to do in main( ) is create a GreenhouseControls object and add a Restart object to get it going.
t Restart est responsable de l'initialisation du système, il ajoute donc tous les événements appropriés. Bien sûr, une manière plus flexible de réaliser ceci serait d'éviter le codage en dur des événements et de les extraire d'un fichier à la place (c'est précisément ce qu'un exercice du Chapitre 11 demande de faire). Puisque Restart() n'est qu'un objet Event comme un autre, on peut aussi ajouter un objet Restart depuis Restart.action() afin que le système se relance de lui-même régulièrement. Et tout ce qu'on a besoin de faire dans main() est de créer un objet GreenhouseControls et ajouter un objet Restart pour lancer le processus.
t t t
This example should move you a long way toward appreciating the value of inner classes, especially when used within a control framework. However, in Chapter 13 you’ll see how elegantly inner classes are used to describe the actions of a graphical user interface. By the time you finish that chapter you should be fully convinced."_Toc481064662"> t Cet exemple devrait vous avoir convaincu de l'intérêt des classes internes, spécialement dans le cas des structures de contrôle. Si ce n'est pas le cas, dans le Chapitre 13, vous verrez comment les classes internes sont utilisées pour décrire élégamment les actions d'une interface graphique utilisateur. A la fin de ce chapitre vous devriez être complètement convaincu.
t t t

Summary

t

Résumé

t t t
Interfaces and inner classes are more sophisticated concepts than what you’ll find in many OOP languages. For example, there’s nothing like them in C++. Together, they solve the same problem that C++ attempts to solve with its multiple inheritance (MI) feature. However, MI in C++ turns out to be rather difficult to use, while Java interfaces and inner classes are, by comparison, much more accessible.
t Les interfaces et les classes internes sont des concepts plus sophistiqués que ce que vous pourrez trouver dans beaucoup de langages de programmation orientés objets. Par exemple, rien de comparable n'existe en C++. Ensemble, elles résolvent le même problème que celui que le C++ tente de résoudre avec les fonctionnalités de l'héritage multiple. Cependant, l'héritage multiple en C++ se révèle relativement ardu à mettre en oeuvre, tandis que les interfaces et les classes internes en Java sont, en comparaison, d'un abord nettement plus facile.
t t t
Although the features themselves are reasonably straightforward, the use of these features is a design issue, much the same as polymorphism. Over time, you’ll become better at recognizing situations where you should use an interface, or an inner class, or both. But at this point in this book you should at least be comfortable with the syntax and semantics. As you see these language features in use you’ll eventually internalize them.
t Bien que les fonctionnalités en elles-mêmes soient relativement simples, leur utilisation relève de la conception, de même que le polymorphisme. Avec le temps, vous reconnaîtrez plus facilement les situations dans lesquelles utiliser une interface, ou une classe interne, ou les deux. Mais à ce point du livre vous devriez à tout le moins vous sentir à l'aise avec leur syntaxe et leur sémantique. Vous intègrerez ces techniques au fur et à mesure que vous les verrez utilisées.
t t t

Exercises

t

Exercices

t t t
Solutions to selected exercises can be found in the electronic document The Thinking in Java Annotated Solution Guide, available for a small fee from www.BruceEckel.com.
t Les solutions d'exercices sélectionnés peuvent être trouvées dans le document électronique The Thinking in Java Annotated Solution Guide, disponible pour un faible coût sur www.BruceEckel.com.
t t t
  1. Prove that the fields in an interface are implicitly static and final.
  2. Create an interface containing three methods, in its own package. Implement the interface in a different package.
  3. Prove that all the methods in an interface are automatically public.
  4. In c07:Sandwich.java, create an interface called FastFood (with appropriate methods) and change Sandwich so that it also implements FastFood.
  5. Create three interfaces, each with two methods. Inherit a new interface from the three, adding a new method. Create a class by implementing the new interface and also inheriting from a concrete class. Now write four methods, each of which takes one of the four interfaces as an argument. In main( ), create an object of your class and pass it to each of the methods.
  6. Modify Exercise 5 by creating an abstract class and inheriting that into the derived class.
  7. Modify Music5.java by adding a Playable interface. Remove the play( ) declaration from Instrument. Add Playable to the derived classes by including it in the implements list. Change tune( ) so that it takes a Playable instead of an Instrument.
  8. Change Exercise 6 in Chapter 7 so that Rodent is an interface.
  9. In Adventure.java, add an interface called CanClimb, following the form of the other interfaces.
  10. Write a program that imports and uses Month2.java.
  11. Following the example given in Month2.java, create an enumeration of days of the week.
  12. Create an interface with at least one method, in its own package. Create a class in a separate package. Add a protected inner class that implements the interface. In a third package, inherit from your class and, inside a method, return an object of the protected inner class, upcasting to the interface during the return.
  13. Create an interface with at least one method, and implement that interface by defining an inner class within a method, which returns a reference to your interface.
  14. Repeat Exercise 13 but define the inner class within a scope within a method.
  15. Repeat Exercise 13 using an anonymous inner class.
  16. Create a private inner class that implements a public interface. Write a method that returns a reference to an instance of the private inner class, upcast to the interface. Show that the inner class is completely hidden by trying to downcast to it.
  17. Create a class with a nondefault constructor and no default constructor. Create a second class that has a method which returns a reference to the first class. Create the object to return by making an anonymous inner class that inherits from the first class.
  18. Create a class with a private field and a private method. Create an inner class with a method that modifies the outer class field and calls the outer class method. In a second outer class method, create an object of the inner class and call it’s method, then show the effect on the outer class object.
  19. Repeat Exercise 18 using an anonymous inner class.
  20. Create a class containing a static inner class. In main( ), create an instance of the inner class.
  21. Create an interface containing a static inner class. Implement this interface and create an instance of the inner class.
  22. Create a class containing an inner class that itself contains an inner class. Repeat this using static inner classes. Note the names of the .class files produced by the compiler.
  23. Create a class with an inner class. In a separate class, make an instance of the inner class.
  24. Create a class with an inner class that has a nondefault constructor. Create a second class with an inner class that inherits from the first inner class.
  25. Repair the problem in WindError.java.
  26. Modify Sequence.java by adding a method getRSelector( ) that produces a different implementation of the Selector interface that moves backward through the sequence from the end to the beginning.
  27. Create an interface U with three methods. Create a class A with a method that produces a reference to a U by building an anonymous inner class. Create a second class B that contains an array of U. B should have one method that accepts and stores a reference to a U in the array, a second method that sets a reference in the array (specified by the method argument) to null and a third method that moves through the array and calls the methods in U. In main( ), create a group of A objects and a single B. Fill the B with U references produced by the A objects. Use the B to call back into all the A objects. Remove some of the U references from the B.
  28. In GreenhouseControls.java, add Event inner classes that turn fans on and off.
  29. Show that an inner class has access to the private elements of its outer class. Determine whether the reverse is true.
t
  1. Prouvez que les champs d'une interface sont implicitement static et final.
  2. Créez une interface contenant trois méthodes, dans son propre package. Implémentez cette interface dans un package différent.
  3. Prouvez que toutes les méthodes d'une interface sont automatiquement public.
  4. Dans c07:Sandwich.java, créez une interface appelée FastFood (avec les méthodes appropriées) et changez Sandwich afin qu'il implémente FastFood.
  5. Créez trois interfaces, chacune avec deux méthodes. Créez une nouvelle interface héritant des trois, en ajoutant une nouvelle méthode. Créez une classe implémentant la nouvelle interface et héritant déjà d'une classe concrète. Ecrivez maintenant quatre méthodes, chacune d'entre elles prenant l'une des quatre interfaces en argument. Dans main(), créez un objet de votre classe et passez-le à chacune des méthodes.
  6. Modifiez l'exercice 5 en créant une classe abstract et en la dérivant dans la dernière classe.
  7. Modifiez Music5.java en ajoutant une interfacePlayable. Enlevez la déclaration de play() d'Instrument. Ajoutez Playable aux classes dérivées en l'incluant dans la liste implements. Changez tune() afin qu'il accepte un Playable au lieu d'un Instrument.
  8. Changez l'exercice 6 du Chapitre 7 afin que Rodent soit une interface.
  9. Dans Adventure.java, ajoutez une interface appelée CanClimb respectant la forme des autres interfaces.
  10. Ecrivez un programme qui importe et utilise Month2.java.
  11. En suivant l'exemple donné dans Month2.java, créez une énumération des jours de la semaine.
  12. Créez une interface dans son propre package contenant au moins une méthode. Créez une classe dans un package séparé. Ajoutez une classe interne protected qui implémente l'interface. Dans un troisième package, dérivez votre classe, et dans une méthode renvoyez un objet de la classe interne protected, en le transtypant en interface durant le retour.
  13. Créez une interface contenant au moins une méthode, et implémentez cette interface en définissant une classe interne à l'intérieur d'une méthode, qui renvoie une référence sur votre interface.
  14. Répétez l'exercice 13 mais définissez la classe interne à l'intérieur d'une portée à l'intérieur de la méthode.
  15. Répétez l'exercice 13 en utilisant une classe interne anonyme.
  16. Créez une classe interne private qui implémente une interface public. Ecrivez une méthode qui renvoie une référence sur une instance de la classe interne private, transtypée en interface. Montrez que la classe interne est complètement cachée en essayant de la transtyper à nouveau.
  17. Créez une classe avec un constructeur autre que celui par défaut et sans constructeur par défaut. Créez une seconde classe disposant d'une méthode qui renvoie une référence à la première classe. Créez un objet à renvoyer en créant une classe interne anonyme dérivée de la première classe.
  18. Créez une classe avec un champ private et une méthode private. Créez une classe interne avec une méthode qui modifie le champ de la classe externe et appelle la méthode de la classe externe. Dans une seconde méthode de la classe externe, créez un objet de la classe interne et appelez sa méthode ; montrez alors l'effet sur l'objet de la classe externe.
  19. Répétez l'exercice 18 en utilisant une classe interne anonyme.
  20. Créez une classe contenant une classe interne static. Dans main(), créez une instance de la classe interne.
  21. Créez une interface contenant une classe interne static. Implémentez cette interface et créez une instance de la classe interne.
  22. Créez une classe contenant une classe interne contenant elle-même une classe interne. Répétez ce schéma en utilisant des classes internes static. Notez les noms des fichiers .class produits par le compilateur.
  23. Créez une classe avec une classe interne. Dans une classe séparée, créez une instance de la classe interne.
  24. Créez une classe avec une classe interne disposant d'un constructeur autre que celui par défaut. Créez une seconde classe avec une classe interne héritant de la première classe interne.
  25. Corrigez le problème dans WindError.java.
  26. Modifiez Sequence.java en ajoutant une méthode getRSelector() qui produise une implémentation différente de l'interface Selector afin de parcourir la séquence en ordre inverse, de la fin vers le début.
  27. Créez une interface U contenant trois méthodes. Créez une classe A avec une méthode qui produise une référence sur un U en construisant une classe interne anonyme. Créez une seconde classe B qui contienne un tableau de U. B doit avoir une méthode qui accepte et stocke une référence sur un U dans le tableau, une deuxième méthode qui positionne une référence (spécifiée par un argument de la méthode) dans le tableau à null, et une troisième méthode qui se déplace dans le tableau et appelle les méthodes de l'objet U. Dans main(), créez un groupe d'objets A et un objet B. Remplissez l'objet B avec les références U produites par les objets A. Utilisez B pour revenir dans les objets A. Enlevez certaines des références U de B.
  28. Dans GreenhouseControls.java, ajoutez des classes internes Event qui contrôlent des ventilateurs.
  29. Montrez qu'une classe interne peut accéder aux éléments private de sa classe externe. Déterminez si l'inverse est vrai.
t t t
[38] This approach was inspired by an e-mail from Rich Hoffarth.
t [38]Cette approche m'a été inspirée par un e-mail de Rich Hoffarth.
t t t
[39] Thanks to Martin Danner for asking this question during a seminar.
t [39]Merci à Martin Danner pour avoir posé cette question lors d'un séminaire.
t t t
[40] This is very different from the design of nested classes in C++, which is simply a name-hiding mechanism. There is no link to an enclosing object and no implied permissions in C++.
t [40]Ceci est très différent du concept des classes imbriquées en C++, qui est simplement un mécanisme de camouflage de noms. Il n'y a aucun lien avec l'objet externe et aucune permission implicite en C++.
t t t
[41] Thanks again to Martin Danner.
t [41]Merci encore à Martin Danner.
t t t
[42] On the other hand, ‘$’ is a meta-character to the Unix shell and so you’ll sometimes have trouble when listing the .class files. This is a bit strange coming from Sun, a Unix-based company. My guess is that they weren’t considering this issue, but instead thought you’d naturally focus on the source-code files.
t [42]Attention cependant, '$' est un méta-caractère pour les shells unix et vous pourrez parfois rencontrer des difficultés en listant les fichiers .class. Ceci peut paraître bizarre de la part de Sun, une entreprise résolument tournée vers unix. Je pense qu'ils n'ont pas pris en compte ce problème car ils pensaient que l'attention se porterait surtout sur les fichiers sources.
t t t
[43] For some reason this has always been a pleasing problem for me to solve; it came from my earlier book C++ Inside & Out, but Java allows a much more elegant solution.
[ Previous Chapter ] [ Short TOC ] [ Table of Contents ] [ Index ] [ Next Chapter ]
Last Update:04/24/2000
t [43]Pour je ne sais quelle raison, ce problème m'a toujours semblé plaisant ; il vient de mon livre précédent C++ Inside & Out, mais Java offre une solution bien plus élégante.
t t t
t t t
t t
\\\
    
t t t
t
     
Sommaire Le site de Bruce Eckel