t
t
t
t
t t   7) Polymorphisme
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 7) Polymorphisme carre8) 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 Dannoville
t
t
///
Ce chapitre contient 4 pages
1 2 3 4
    
t t t
t t t
t
t t t
As in the diagram, MoreUseful extends the interface of Useful. But since it’s inherited, it can also be upcast to a Useful. You can see this happening in the initialization of the array x in main( ). Since both objects in the array are of class Useful, you can send the f( ) and g( ) methods to both, and if you try to call u( ) (which exists only in MoreUseful) you’ll get a compile-time error message.
t Comme dans le diagramme, MoreUseful étend l'interface de Useful. Mais puisque il a hérité, on peut faire un upcast vers un Useful. Vous pouvez voir ceci se produire dans l'initialisation du tableau x dans main(). Comme les deux objets du tableau sont de la classe Useful, vous pouvez envoyer les méthodes f() et g() aux deux, et si vous essayer d'invoquer u(), qui existe seulement dans MoreUseful, vous aurez un message d'erreur à la compilation.
t t t
If you want to access the extended interface of a MoreUseful object, you can try to downcast. If it’s the correct type, it will be successful. Otherwise, you’ll get a ClassCastException. You don’t need to write any special code for this exception, since it indicates a programmer error that could happen anywhere in a program.
t Si vous voulez accéder à l'interface étendue d'un objet MoreUseful, vous pouvez essayer un downcast. Si c'est le type correct, cela fonctionnera. Autrement, vous allez recevoir une ClassCastException. Vous n'avez pas besoin d'écrire un code spécial pour cette exception, car elle indique une erreur du programmeur qui pourrait arriver n'importe où dans un programme.
t t t
There’s more to RTTI than a simple cast. For example, there’s a way to see what type you’re dealing with before you try to downcast it. All of Chapter 12 is devoted to the study of different aspects of Java run-time type identification.
t La RTTI est plus riche qu'un simple cast. Par exemple, il y a une façon de connaître le type que vous manipulez avant d'essayer de le downcaster. Tout le Chapitre 12 est consacré à l'étude de différents aspects du « run-time type identification » Java.
t t t

Summary

t

Résumé

t t t
Polymorphism means “different forms.” In object-oriented programming, you have the same face (the common interface in the base class) and different forms using that face: the different versions of the dynamically bound methods.
t Polymorphisme signifie « différentes formes. » Dans la programmation orientée objet, vous avez la même physionomie (l'interface commune dans la classe de base) et différentes formes qui utilisent cette physionomie: les différentes versions des méthodes dynamiquement attachées.
t t t
You’ve seen in this chapter that it’s impossible to understand, or even create, an example of polymorphism without using data abstraction and inheritance. Polymorphism is a feature that cannot be viewed in isolation (like a switch statement can, for example), but instead works only in concert, as part of a “big picture” of class relationships. People are often confused by other, non-object-oriented features of Java, like method overloading, which are sometimes presented as object-oriented. Don’t be fooled: If it isn’t late binding, it isn’t polymorphism.
t Vous avez vu dans ce chapitre qu'il est impossible de comprendre, ou même créer, un exemple de polymorphisme sans utiliser l'abstraction et l'héritage. Le polymorphisme est une notion qui ne peut pas être présenté séparément (comme on peut le faire par exemple avec un switch), mais qui fonctionne plutôt en conjonction avec le schéma global #big picture# des relation entre classes. Les gens sont souvent troublés par d'autres dispositifs non-orientés objet de Java, comme la surcharge de méthode, qui sont parfois présentés comme étant orientés objet. Ne soyez pas dupe: si ce n'est pas de la liaison tardive, ce n'est pas du polymorphisme.
t t t
To use polymorphism—and thus object-oriented techniques—effectively in your programs you must expand your view of programming to include not just members and messages of an individual class, but also the commonality among classes and their relationships with each other. Although this requires significant effort, it’s a worthy struggle, because the results are faster program development, better code organization, extensible programs, and easier code maintenance.
t Pour utiliser le polymorphisme, et par conséquent les techniques orientées objet, pertinemment dans vos programmes vous devez élargir votre vision de la programmation pour y inclure non seulement les membres et les messages d'une classe individuelle, mais également ce qui est partagé entre les classes et leurs rapports entre elles. Bien que ceci exige un effort significatif, ça vaut vraiment le coup car il en résulte un développement plus rapide, un code mieux organisé, des programmes extensibles et une maintenance plus facile.
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
t t t
  1. Add a new method in the base class of Shapes.java that prints a message, but don’t override it in the derived classes. Explain what happens. Now override it in one of the derived classes but not the others, and see what happens. Finally, override it in all the derived classes.
  2. Add a new type of Shape to Shapes.java and verify in main( ) that polymorphism works for your new type as it does in the old types.
  3. Change Music3.java so that what( ) becomes the root Object method toString( ). Try printing the Instrument objects using System.out.println( ) (without any casting).
  4. Add a new type of Instrument to Music3.java and verify that polymorphism works for your new type.
  5. Modify Music3.java so that it randomly creates Instrument objects the way Shapes.java does.
  6. Create an inheritance hierarchy of Rodent: Mouse, Gerbil, Hamster, etc. In the base class, provide methods that are common to all Rodents, and override these in the derived classes to perform different behaviors depending on the specific type of Rodent. Create an array of Rodent, fill it with different specific types of Rodents, and call your base-class methods to see what happens.
  7. Modify Exercise 6 so that Rodent is an abstract class. Make the methods of Rodent abstract whenever possible.
  8. Create a class as abstract without including any abstract methods, and verify that you cannot create any instances of that class.
  9. Add class Pickle to Sandwich.java.
  10. Modify Exercise 6 so that it demonstrates the order of initialization of the base classes and derived classes. Now add member objects to both the base and derived classes, and show the order in which their initialization occurs during construction.
  11. Create a 3-level inheritance hierarchy. Each class in the hierarchy should have a finalize( ) method, and it should properly call the base-class version of finalize( ). Demonstrate that your hierarchy works properly.
  12. Create a base class with two methods. In the first method, call the second method. Inherit a class and override the second method. Create an object of the derived class, upcast it to the base type, and call the first method. Explain what happens.
  13. Create a base class with an abstract print( ) method that is overridden in a derived class. The overridden version of the method prints the value of an int variable defined in the derived class. At the point of definition of this variable, give it a nonzero value. In the base-class constructor, call this method. In main( ), create an object of the derived type, and then call its print( ) method. Explain the results.
  14. Following the example in Transmogrify.java, create a Starship class containing an AlertStatus reference that can indicate three different states. Include methods to change the states.
  15. Create an abstract class with no methods. Derive a class and add a method. Create a static method that takes a reference to the base class, downcasts it to the derived class, and calls the method. In main( ), demonstrate that it works. Now put the abstract declaration for the method in the base class, thus eliminating the need for the downcast.
t
  1. Ajouter une nouvelle méthode à la classe de base de Shapes.java qui affiche un message, mais sans la redéfinir dans les classes dérivées. Expliquer ce qui se passe. Maintenant la redéfinir dans une des classes dérivées mais pas dans les autres, et voir ce qui se passe. Finalement, la redéfinir dans toutes les classes dérivées.
  2. Ajouter un nouveau type de Shape à Shapes.java et vérifier dans main() que le polymorphisme fonctionne pour votre nouveau type comme il le fait pour les anciens types.
  3. Changer Music3.java pour que what() devienne une méthode toString() de la classe racine Object . Essayer d'afficher les objets Instrument en utilisant System.out.println() (sans aucun cast).
  4. Ajouter un nouveau type d'Instrument à Music3.java et vérifier que le polymorphisme fonctionne pour votre nouveau type.
  5. Modifier Music3.java pour qu'il crée de manière aléatoire des objets Instrument de la même façon que Shapes.java le fait.
  6. Créer une hiérarchie d'héritage de Rongeur: Souris, Gerbille, Hamster, etc. Dans la classe de base, fournir des méthodes qui sont communes à tous les Rongeurs, et les redéfinir dans les classes dérivées pour exécuter des comportements différents dépendant du type spécifique du Rongeur. Créer un tableau de Rongeur, le remplir avec différent types spécifiques de Rongeurs, et appeler vos méthodes de la classe de base pour voir ce qui arrive.
  7. Modifier l'Exercice 6 pour que Rongeur soit une classe abstract. Rendre les méthodes de Rongeur abstraites dès que possible.
  8. Créer une classe comme étant abstract sans inclure aucune méthode abstract, et vérifier que vous ne pouvez créer aucune instance de cette classe.
  9. Ajouter la classe Pickle à Sandwich.java.
  10. Modifier l'Exercice 6 afin qu'il démontre l'ordre des initialisations des classes de base et des classes dérivées. Maintenant ajouter des objets membres à la fois aux classes de base et dérivées, et montrer dans quel ordre leurs initialisations se produisent durant la construction.
  11. Créer une hiérarchie d'héritage à 3 niveaux. Chaque classe dans la hiérarchie devra avoir une méthode finalize(), et devra invoquer correctement la version de la classe de base de finalize(). Démontrer que votre hiérarchie fonctionne de manière appropriée.
  12. Créer une classe de base avec deux méthodes. Dans la première méthode, appeler la seconde méthode. Faire hériter une classe et redéfinir la seconde méthode. Créer un objet de la classe dérivée, upcaster le vers le type de base, et appeler la première méthode. Expliquer ce qui se passe.
  13. Créer une classe de base avec une méthode abstract print() qui est redéfinie dans une classe dérivée. La version redéfinie de la méthode affiche la valeur d'une variable int définie dans la classe dérivée. Au point de définition de cette variable, lui donner une valeur non nulle. Dans le constructeur de la classe de base, appeler cette méthode. Dans main(), créer un objet du type dérivé, et ensuite appeler sa méthode print(). Expliquer les résultats.
  14. Suivant l'exemple de Transmogrify.java, créer une classe Starship contenant une référence AlertStatus qui peut indiquer trois états différents. Inclure des méthodes pour changer les états.
  15. Créer une classe abstract sans méthodes. Dériver une classe et ajouter une méthode. Créer une méthode static qui prend une référence vers la classe de base, effectue un downcast vers la classe dérivée, et appelle la méthode. Dans main(), démontrer que cela fonctionne. Maintenant mettre la déclaration abstract pour la méthode dans la classe de base, éliminant ainsi le besoin du downcast.
t t t
[37] For C++ programmers, this is the analogue of C++’s pure virtual function.
[ Previous Chapter ] [ Short TOC ] [ Table of Contents ] [ Index ] [ Next Chapter ]
Last Update:04/24/2000
t [37] Pour les programmeurs C++, ceci est analogue aux fonctions virtuelles pures du C++.
t t t
t t t
t t
\\\
    
t t t
t
     
Sommaire Le site de Bruce Eckel