 |
 |
 |
7) Polymorphisme |
|
 |
|
Texte original |
 |
Traducteur : Jérome DANNOVILLE |
|
 |
///
|
Ce chapitre contient 4 pages
1
2
3
4
|
|
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
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.
|
 |
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.
|
 |
 |
 |
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.
|
 |
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.
|
 |
 |
 |
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.
|
 |
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.
|
 |
 |
 |
Summary
|
 |
Résumé
|
 |
 |
 |
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.
|
 |
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.
|
 |
 |
 |
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.
|
 |
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.
|
 |
 |
 |
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.
|
 |
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.
|
 |
 |
 |
Exercises
|
 |
Exercices
|
 |
 |
 |
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.
|
 |
|
 |
 |
 |
- 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.
- 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.
- Change
Music3.java so that what( ) becomes the root Object
method toString( ). Try printing the Instrument objects
using System.out.println( ) (without any
casting).
- Add a new
type of Instrument to Music3.java and verify that polymorphism
works for your new
type.
- Modify
Music3.java so that it randomly creates Instrument objects the way
Shapes.java
does.
- 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.
- Modify
Exercise 6 so that Rodent is an abstract class. Make the methods
of Rodent abstract whenever
possible.
- Create a
class as abstract without including any abstract methods, and
verify that you cannot create any instances of that
class.
- Add class
Pickle to
Sandwich.java.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
|
 |
- 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.
- 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.
- 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).
- Ajouter un nouveau type d'Instrument à
Music3.java et vérifier que le polymorphisme fonctionne pour votre nouveau
type.
- 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.
- 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.
- Modifier l'Exercice 6 pour que Rongeur soit une classe
abstract. Rendre les méthodes de Rongeur abstraites dès que
possible.
- 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.
- Ajouter la classe Pickle à
Sandwich.java.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
|
 |
 |
 |
[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
|
 |
[37] Pour les programmeurs C++,
ceci est analogue aux fonctions virtuelles pures du C++.
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
|
 |