 |
 |
5) Cacher l'implémentation |
|
 |
|
Texte original |
 |
Traducteur : Phillipe BOITE |
|
 |
///
|
Ce chapitre contient 3 pages
1
2
3
|
|
|
 |
 |
 |
 |
 |
 |
|
 |
|
 |
 |
 |
Interface and implementation
|
 |
Interface et implémentation
|
 |
 |
 |
Access control is often referred to as
implementation hiding.
Wrapping data and methods within classes in combination with implementation
hiding is often called
encapsulation[34].
The result is a data type with characteristics and behaviors.
|
 |
Le contrôle d'accès est souvent appelé cacher l'implémentation
[implementation hiding] . L'enveloppement [wrapping] des données et méthodes à
l'intérieur des classes combiné au masquage de l'implémentation est souvent appelé
encapsulation [34]. Le résultat
est un type de données avec des caractéristiques et des comportements.
|
 |
 |
 |
Access control puts boundaries within a
data type for two important reasons. The first is to establish what the client
programmers can and can’t use. You can build your internal mechanisms into
the structure without worrying that the client programmers will accidentally
treat the internals as part of the interface that they should be
using.
|
 |
Le contrôle d'accès pose des limites sur un type de données pour deux
raisons importantes. La première est de déterminer ce que les programmeurs clients peuvent et ne
peuvent pas utiliser. On peut construire les mécanismes internes dans la structure sans se
préoccuper du risque que les programmeurs clients prennent ces mécanismes internes comme faisant
partie de l'interface qu'ils doivent utiliser.
|
 |
 |
 |
This feeds directly into the second
reason, which is to separate the interface from the implementation.
If the
structure is used in a set of programs, but client programmers can’t do
anything but send messages to the public interface, then you can change
anything that’s not public (e.g., “friendly,”
protected, or private) without requiring modifications to client
code.
|
 |
Ceci amène directement à la deuxième raison, qui est de séparer l'interface
de son implémentation. Si la structure est utilisée dans un ensemble de
programmes, mais que les programmeurs clients ne peuvent qu'envoyer des messages à l'interface
public, alors on peut modifier tout ce qui n'est pas
public (c'est à dire « amical », protected, ou
private) sans que cela nécessite des modifications du code client.
|
 |
 |
 |
We’re now in the world of
object-oriented programming, where a class is actually describing
“a class of objects,” as you would describe a class of fishes or a
class of birds. Any object belonging to this class will share these
characteristics and behaviors. The class is a description of the way all objects
of this type will look and act.
|
 |
Nous sommes maintenant dans le monde de la programmation orientée objet,
dans lequel une class est en fait la description d' « une classe d'objets », comme
on décrirait une classe des poissons ou une classe des oiseaux. Tout objet appartenant à cette
classe partage ces caractéristiques et comportements. La classe est une description de la façon
dont les objets de ce type vont nous apparaître et se comporter.
|
 |
 |
 |
In the original OOP
language, Simula-67, the keyword
class was used to describe a new data type. The
same keyword has been used for most object-oriented languages. This is the focal
point of the whole language: the creation of new data types that are more than
just boxes containing data and methods.
|
 |
Dans le langage de POO d'origine, Simula-67 , le mot-clé
class était utilisé pour décrire un nouveau type de données. Le même mot-clé a été
repris dans la plupart des langages orientés objet. Ceci est le point central de tout le langage :
la création de nouveaux types de données qui sont plus que simplement des boîtes contenant des
données et des méthodes.
|
 |
 |
 |
The class is the fundamental OOP concept
in Java. It is one of the keywords that will not be set in bold in this
book—it becomes annoying with a word repeated as often as
“class.”
|
 |
La classe est le concept de POO fondamental en Java. C'est l'un des
mots-clés qui ne sera pas mis en gras dans ce livre, ça devient lourd pour un mot aussi
souvent répété que « class ».
|
 |
 |
 |
For clarity, you might prefer a
style of creating classes that
puts the public members at the beginning, followed by the
protected, friendly, and private members. The advantage is that
the user of the class can then read down from the top and see first what’s
important to them (the public members, because they can be accessed
outside the file), and stop reading when they encounter the non-public
members, which are part of the internal implementation:
|
 |
Pour plus de clarté, il est préférable d'utiliser un style de création des
classes qui place les membres public au début, suivi par les membres
protected, amicaux et private. L'avantage de ceci est que
l'utilisateur de la classe peut voir ce qui est important pour lui (les membres
public, parce qu'on peut y accéder de l'extérieur du fichier), en lisant depuis le
début et en s'arrêtant lorsqu'il rencontre les membres non-public, qui font partie
de l'implémentation interne :
|
 |
 |
 |
public class X { public void pub1( ) { /* . . . */ } public void pub2( ) { /* . . . */ } public void pub3( ) { /* . . . */ } private void priv1( ) { /* . . . */ } private void priv2( ) { /* . . . */ } private void priv3( ) { /* . . . */ } private int i; // . . . }
|
 |
public class X { public void pub1( ) { /* . . . */ } public void pub2( ) { /* . . . */ } public void pub3( ) { /* . . . */ } private void priv1( ) { /* . . . */ } private void priv2( ) {/* . . . */ } private void priv3( ) { /* . . . */ } private int i; // . . . }
|
 |
 |
 |
This will make it only partially easier
to read because the interface and implementation are still mixed together. That
is, you still see the source code—the implementation—because
it’s right there in the class. In addition, the comment documentation
supported by javadoc (described in Chapter 2) lessens the importance of code
readability by the client programmer. Displaying the interface to the consumer
of a class is really the job of the
class browser, a tool whose
job is to look at all the available classes and show you what you can do with
them (i.e., what members are available) in a useful fashion. By the time you
read this, browsers should be an expected part of any good Java development
tool.
|
 |
Ceci ne la rendra que partiellement plus lisible parce que l'interface et
l'implémentation sont encore mélangés. C'est-à-dire qu'on voit toujours le code source
(l'implémentation) parce qu'il est là dans la classe. Cependant, la documentation sous forme de
commentaires supportée par javadoc (décrite au Chapitre 2) diminue l'importance de la lisibilité du
code par le programmeur client. Afficher l'interface au consommateur d'une classe est normalement
le travail du class browser, un outil dont le travail consiste à inspecter toutes les
classes disponibles et de montrer ce qu'on peut en faire (c'est à dire quels membres sont
disponibles) de façon pratique. Au moment où vous lisez ceci, les browsers devraient faire partie
de tout bon outil de développement Java.
|
 |
 |
 |
Class access
|
 |
L'accès aux classes
|
 |
 |
 |
In Java, the access specifiers can also
be used to determine which classes within a library will be available to
the users of that library. If you want a class to be available to a client
programmer, you place the public keyword somewhere before the opening
brace of the class body. This controls whether the client programmer can even
create an object of the class.
|
 |
En Java, les spécificateurs d'accès peuvent aussi être utilisés pour
déterminer quelles classes d'une bibliothèque seront accessibles aux utilisateurs de cette
bibliothèque. Si on désire qu'une classe soit disponible pour un programmeur client, on place le
mot-clé public quelque part devant l'accolade ouvrante du corps de la classe. Ceci
permet de contrôler le fait même qu'un programmeur client puisse créer un objet de cette
classe.
|
 |
 |
 |
To control the access of a class, the
specifier must appear before the keyword class. Thus you can
say:
|
 |
Pour contrôler l'accès à la classe, le spécificateur doit apparaître avant
le mot-clé class. Donc on peut dire :
|
 |
 |
 |
public class Widget {
|
 |
public class Widget {
|
 |
 |
 |
Now if the name of your library is mylib any client programmer can access Widget by saying
|
 |
Maintenant, si le nom de la bibliothèque est mylib, tout
programmeur client peut accéder à Widget en disant
|
 |
 |
 |
import mylib.Widget;
|
 |
import mylib.Widget;
|
 |
 |
 |
or
|
 |
ou
|
 |
 |
 |
import mylib.*;
|
 |
import mylib.*;
|
 |
 |
 |
However, there’s an extra set of constraints:
|
 |
Il y a cependant un ensemble de contraintes supplémentaires :
|
 |
 |
 |
- There can be only one
public class per compilation unit (file). The idea is that each compilation unit has a single public interface represented by that public class. It can have as many supporting “friendly” classes as you want. If you have more than one public class inside a compilation unit, the compiler will give you an error message.
- The name of
the public class must exactly match the name of the file containing the compilation unit, including capitalization. So for Widget, the name of the file must be Widget.java, not widget.java or WIDGET.java. Again, you’ll get a compile-time error if they don’t agree.
- It is
possible, though not typical, to have a compilation unit with no public class at all. In this case, you can name the file whatever you like.
|
 |
- Il ne peut y avoir qu'une seule classe public par unité
de compilation (fichier). L'idée est que chaque unité de compilation a une seule interface publique
représentée par cette classe public . Elle peut avoir autant de classes « amicales »
de support qu'on veut. Si on a plus d'une classe public dans une unité de
compilation, le compilateur générera un message d'erreur.
- Le nom de la classe public doit correspondre exactement
au nom du fichier contenant l'unité de compilation, y compris les majuscules et minuscules. Par
exemple pour Widget, le nom du fichier doit être Widget.java, et
pas widget.java ou WIDGET.java. Là aussi on obtient des erreurs
de compilation s'ils ne correspondent pas.
- Il est possible, bien que non habituel, d'avoir une unité de compilation
sans aucune classe public. Dans ce cas, on peut appeler le fichier comme on
veut.
|
 |
 |
 |
What if you’ve got a class inside mylib that you’re just using to accomplish the tasks performed by Widget or some other public class in mylib? You don’t want to go to the bother of creating documentation for the client programmer, and you think that sometime later you might want to completely change things and rip out your class altogether, substituting a different one. To give you this flexibility, you need to ensure that no client programmers become dependent on your particular implementation details hidden inside mylib. To accomplish this, you just leave the public keyword off the class, in which case it becomes friendly. (That class can be used only within that package.)
|
 |
Que se passe-t-il si on a une classe dans mylib qu'on
utilise uniquement pour accomplir les tâches effectuées par Widget ou une autre
classe public de mylib ? On ne veut pas créer de documentation pour un programmeur
client, et on pense que peut-être plus tard on modifiera tout et qu'on refera toute la classe en
lui en substituant une nouvelle. Pour garder cette possibilité, il faut s'assurer qu'aucun
programmeur client ne devienne dépendant des détails d'implémentation cachés dans
mylib. Pour réaliser ceci il suffit d'enlever le mot-clé public
de la classe, qui devient dans ce cas amicale. (Cette classe ne peut être utilisée que dans ce
package.)
|
 |
 |
 |
Note that a class cannot be private (that would make it accessible to no one but the class), or protected[35]. So you have only two choices for class access: “friendly” or public. If you don’t want anyone else to have access to that class, you can make all the constructors private, thereby preventing anyone but you, inside a static member of the class, from creating an object of that class[36]. Here’s an example:
|
 |
Remarquez qu'une classe ne peut pas être private (cela ne
la rendrait accessible à personne d'autre que cette classe), ou protected [35]. Il n'y a donc que deux choix pour l'accès aux classes : « amical » ou
public. Si on ne veut pas que quelqu'un d'autre accède à cette classe, on peut
rendre tous les constructeurs private, ce qui empêche tout le monde de créer un
objet de cette classe, à part soi-même dans un membre static de la classe [36]. Voici un exemple :
|
 |
 |
 |
//: c05:Lunch.java // Demonstrates class access specifiers. // Make a class effectively private // with private constructors:
class Soup { private Soup() {} // (1) Allow creation via static method: public static Soup makeSoup() { return new Soup(); } // (2) Create a static object and // return a reference upon request. // (The "Singleton" pattern): private static Soup ps1 = new Soup(); public static Soup access() { return ps1; } public void f() {} }
class Sandwich { // Uses Lunch void f() { new Lunch(); } }
// Only one public class allowed per file: public class Lunch { void test() { // Can't do this! Private constructor: //! Soup priv1 = new Soup(); Soup priv2 = Soup.makeSoup(); Sandwich f1 = new Sandwich(); Soup.access().f(); } } ///:~
|
 |
//: c05:Lunch.java // Démontre les spécificateurs d'accès de classes. // Faire une classe effectivement private // avec des constructeurs private : class Soup { private Soup() {} // (1) Permettre la création à l'aide d'une méthode static : public static Soup makeSoup() { return new Soup(); } // (2) Créer un objet static et // retourner une référence à la demande. // (le patron "Singleton"): private static Soup ps1 = new Soup(); public static Soup access() { return ps1; } public void f() {} }
class Sandwich { // Utilise Lunch void f() { new Lunch(); } }
// Une seule classe public autorisée par fichier : public class Lunch { void test() { // Ne peut pas faire ceci ! Constructeur privé : //! Soup priv1 = new Soup(); Soup priv2 = Soup.makeSoup(); Sandwich f1 = new Sandwich(); Soup.access().f(); } } ///:~
|
 |
 |
 |
Up to now, most of the methods have been
returning either void or a primitive type, so the
definition:
|
 |
Jusqu'ici, la plupart des méthodes retournaient soit void
soit un type primitif, ce qui fait que la définition :
|
 |
 |
 |
public static Soup access() { return ps1; }
|
 |
public static Soup access() { return ps1; }
|
 |
 |
 |
might look a little confusing at first.
The word before the method name (access) tells what the method returns.
So far this has most often been void, which means it returns nothing. But
you can also return a reference to an object, which is what happens here. This
method returns a reference to an object of class Soup.
|
 |
pourrait paraître un peu confuse. Le mot devant le nom de la méthode
(access) dit ce que retourne la méthode. Jusqu'ici cela a été le plus souvent
void, ce qui signifie qu'elle ne retourne rien. Mais on peut aussi retourner la
référence à un objet, comme c'est le cas ici. Cette méthode retourne une référence à un objet de la
classe Soup.
|
 |
 |
 |
The class Soup shows how to
prevent direct creation of a class by making all the constructors
private. Remember that if you don’t explicitly create at least one
constructor, the default constructor (a constructor with no arguments) will be
created for you. By writing the default constructor, it won’t be created
automatically. By making it private, no one can create an object of that
class. But now how does anyone use this class? The above example shows two
options. First, a static method is created that creates a new Soup
and returns a reference to it. This could be useful if you want to do some extra
operations on the Soup before returning it, or if you want to keep count
of how many Soup objects to create (perhaps to restrict their
population).
|
 |
La classe Soup montre comment empêcher la création directe
d'une classe en rendant tous les constructeurs private. Souvenez-vous que si vous
ne créez pas explicitement au moins un constructeur, le constructeur par défaut (un constructeur
sans arguments) sera créé pour vous. En écrivant ce constructeur par défaut, il ne sera pas créé
automatiquement. En le rendant private, personne ne pourra créer un objet de cette classe. Mais
alors comment utilise-t-on cette classe ? L'exemple ci-dessus montre deux possibilités.
Premièrement, une méthode static est créée, elle créee un nouveau
Soup et en retourne la référence. Ceci peut être utile si on veut faire des
opérations supplémentaires sur Soup avant de le retourner, ou si on veut garder un
compteur du nombre d'objets Soup créés (peut-être pour restreindre leur
population).
|
 |
 |
 |
The second option uses what’s
called a
design
pattern, which is covered in Thinking in Patterns with Java,
downloadable at www.BruceEckel.com. This particular pattern is called a
“singleton” because it allows only a single
object to ever be created. The object of class Soup is created as a
static private member of Soup, so there’s one and
only one, and you can’t get at it except through the public method
access( ).
|
 |
La seconde possibilité utilise ce qu'on appelle un patron de conception
[design pattern], qui est expliqué dans Thinking in Patterns with Java,
téléchargeable sur www.BruceEckel.com. Ce patron particulier est appelé un « singleton »
parce qu'il n'autorise la création que d'un seul objet. L'objet de classe Soup est créé comme un
membre static private de Soup, ce qui fait qu'il
n'y en a qu'un seul, et on ne peut y accéder qu'à travers la méthode public
access().
|
 |
 |
 |
As previously mentioned, if you
don’t put an access specifier for class access it defaults to
“friendly.” This means that an object of that class can be created
by any other class in the package, but not outside the package. (Remember, all
the files within the same directory that don’t have explicit package
declarations are implicitly part of the default package for that directory.)
However, if a static member of that class is public, the client
programmer can still access that static member even though they cannot
create an object of that
class.
|
 |
Comme mentionné précédemment, si on ne met pas de spécificateur d'accès il
est « amical » par défaut. Ceci signifie qu'un objet de cette classe peut être créé par toute autre
classe du package, mais pas en dehors du package (souvenez-vous que tous les fichiers dans le même
répertoire qui n'ont pas de déclaration package explicite font implicitement
partie du package par défaut pour ce répertoire). Cependant, si un membre static
de cette classe est public, le programmeur client peut encore accéder à ce membre
static même s'il ne peut pas créer un objet de cette classe.
|
 |
 |
 |
Summary
|
 |
Résumé
|
 |
 |
 |
In any relationship it’s important
to have boundaries that are respected by all parties involved. When you create a
library, you establish a relationship with the user of that library—the
client programmer—who is another programmer, but one putting together an
application or using your library to build a bigger library.
|
 |
Dans toute relation il est important d'avoir des limites respectées par
toutes les parties concernées. Lorsqu'on crée une bibliothèque, on établit une relation avec
l'utilisateur de cette bibliothèque (le programmeur client) qui est un autre programmeur, mais qui
construit une application ou qui utilise la bibliothèque pour créer une bibliothèque plus
grande.
|
 |
 |
 |
Without rules, client programmers can do
anything they want with all the members of a class, even if you might prefer
they don’t directly manipulate some of the members. Everything’s
naked to the world.
|
 |
Sans règles, les programmeurs clients peuvent faire tout ce qu'ils veulent
des membres de la classe, même si vous préféreriez qu'ils ne manipulent pas directement certains
des membres. Tout est à découvert dans le monde entier.
|
 |
 |
 |
This chapter looked at how classes are
built to form libraries; first, the way a group of classes is packaged within a
library, and second, the way the class controls access to its
members.
|
 |
Ce chapitre a décrit comment les classes sont construites pour former des
bibliothèques ; d'abord, comment un groupe de classes est empaqueté [packaged]dans une
bibliothèque, et ensuite comment la classe contrôle l'accès à ses membres.
|
 |
 |
 |
It is estimated that a C programming
project begins to break down somewhere between 50K and 100K lines of code
because C has a single “name space” so names begin to collide,
causing an extra management overhead. In Java, the package keyword, the
package naming scheme, and the import keyword give you complete control
over names, so the issue of name collision is easily avoided.
|
 |
On estime qu'un projet programmé en C commence à s'écrouler losqu'il
atteint 50K à 100K de lignes de code, parce que le C a un seul « espace de nommage », et donc les
noms commencent à entrer en conflit, provoquant un surcroît de gestion. En Java, le mot-clé
package, le principe de nommage des packages et le mot-clé import
donnent un contrôle complet sur les noms, et le problème de conflit de nommage est facilement
évité.
|
 |
 |
 |
There are two reasons for controlling
access to members. The first is to
keep users’ hands off tools that they shouldn’t touch; tools that
are necessary for the internal machinations of the data type, but not part of
the interface that users need to solve their particular problems. So making
methods and fields private is a service to users because they can easily
see what’s important to them and what they can ignore. It simplifies their
understanding of the class.
|
 |
Il y a deux raisons pour contrôler l'accès aux membres. La première est
d'écarter les utilisateurs des outils qu'ils ne doivent pas utiliser ; outils qui sont nécessaires
pour les traitements internes des types de données, mais qui ne font pas partie de l'interface dont
les utilisateurs ont besoin pour résoudre leurs problèmes particuliers. Donc créer des méthodes et
des champs private est un service rendu aux utilisateurs parce qu'ils peuvent
facilement voir ce qui est important pour eux et ce qu'ils peuvent ignorer. Cela leur simplifie la
compréhension de la classe.
|
 |
 |
 |
The second and most important reason for
access control is to allow the library designer to change the internal workings
of the class without worrying about how it will affect the client programmer.
You might build a class one way at first, and then discover that restructuring
your code will provide much greater speed. If the interface and implementation
are clearly separated and protected, you can accomplish this without forcing the
user to rewrite their code.
|
 |
La deuxième raison, et la plus importante, pour le contrôle d'accès, est de
permettre au concepteur de bibliothèque de modifier les fonctionnements internes de la classe sans
se soucier de la façon dont cela peut affecter le programmeur client. On peut construire une classe
d'une façon, et ensuite découvrir qu'une restructuration du code améliorera grandement sa vitesse.
Si l'interface et l'implémentation sont clairement séparées et protégées, on peut y arriver sans
forcer l'utilisateur à réécrire son code.
|
 |
 |
 |
Access specifiers in Java give valuable control to the creator of a class. The users of the class can clearly see exactly what they can use and what to ignore. More important, though, is the ability to ensure that no user becomes dependent on any part of the underlying implementation of a class. If you know this as the creator of the class, you can change the underlying implementation with the knowledge that no client programmer will be affected by the changes because they can’t access that part of the class. |
 |
Les spécificateurs d'accès en Java donnent un contrôle précieux au créateur
d'une class. Les utilisateurs de la class peuvent voir clairement
et exactement ce qu'ils peuvent utiliser et ce qu'ils peuvent ignorer. Encore plus important, on a
la possiblité de garantir qu'aucun utilisateur ne deviendra dépendant d'une quelconque partie de
l'implémentation d'une class. Sachant cela en tant que créateur d'une
class, on peut en modifier l'implémentation en sachant qu'aucun programmeur client
ne sera affecté par les modifications car il ne peut accéder à cette partie de la
class.
|
 |
 |
 |
When you have the ability to change the underlying implementation, you can not only improve your design later, but you also have the freedom to make mistakes. No matter how carefully you plan and design you’ll make mistakes. Knowing that it’s relatively safe to make these mistakes means you’ll be more experimental, you’ll learn faster, and you’ll finish your project sooner.
|
 |
Lorsqu'on a la possibilité de modifier l'implémentation, on peut non
seulement améliorer la conception plus tard, mais on a aussi le droit de faire des erreurs .
Quelles que soient les soins que vous apportez à votre planning et à votre conception, vous ferez
des erreurs. Savoir qu'il est relativement peu dangereux de faire ces erreurs veut dire que vous
ferez plus d'expériences, vous apprendrez plus vite, et vous finirez plus vite votre
projet.
|
 |
 |
 |
The public interface to a class is what the user does see, so that is the most important part of the class to get “right” during analysis and design. Even that allows you some leeway for change. If you don’t get the interface right the first time, you can add more methods, as long as you don’t remove any that client programmers have already used in their code.
|
 |
L'interface publique d'une classe est ce que l'utilisateur voit,
donc c'est la partie qui doit être « correcte » lors de l'analyse et la conception. Et même ici vous
avez encore quelques possibilités de modifications. Si vous n'avez pas la bonne interface du
premier coup, vous pouvez ajouter des méthodes , pour autant que vous ne supprimiez pas
celles que les programmeurs clients ont déjà utilisé dans leur code.
|
 |
 |
 |
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.
|
 |
Les solutions des exercices sélectionnés sont disponibles dans le
document électronique The Thinking in Java Annotated Solution Guide, disponible à un prix
raisonnable sur www.BruceEckel.com.
|
 |
 |
 |
- Write a program that
creates an ArrayList object without explicitly importing java.util.*. - In
the section labeled “package: the library unit,” turn the code fragments concerning mypackage into a compiling and running set of Java files. - In the
section labeled “Collisions,” take the code fragments and turn them into a program, and verify that collisions do in fact occur. - Generalize
the class P defined in this chapter by adding all the overloaded versions of rint( ) and rintln( ) necessary to handle all the different basic Java types. - Change the
import statement in TestAssert.java to enable and disable the assertion mechanism. - Create a
class with public, private, protected, and “friendly” data members and method members. Create an object of this class and see what kind of compiler messages you get when you try to access all the class members. Be aware that classes in the same directory are part of the “default” package. - Create a
class with protected data. Create a second class in the same file with a method that manipulates the protected data in the first class. - Change the
class Cookie as specified in the section labeled “protected: ‘sort of friendly.’” Verify that bite( ) is not public. - In
the section titled “Class access” you’ll find code fragments describing mylib and Widget. Create this library, then create a Widget in a class that is not part of the mylib package. - Create a
new directory and edit your CLASSPATH to include that new directory. Copy the P.class file (produced by compiling com.bruceeckel.tools.P.java) to your new directory and then change the names of the file, the P class inside and the method names. (You might also want to add additional output to watch how it works.) Create another program in a different directory that uses your new class. - Following the
form of the example Lunch.java, create a class called ConnectionManager that manages a fixed array of Connection objects. The client programmer must not be able to explicitly create Connection objects, but can only get them via a static method in ConnectionManager. When the ConnectionManager runs out of objects, it returns a null reference. Test the classes in main( ). - Create
the following file in the c05/local directory (presumably in your CLASSPATH):
|
 |
- Ecrivez un programme qui crée un objet ArrayList sans importer
explicitement java.util.*.
- Dans la section nommée « package : l'unité de bibliothèque », transformez
les fragments de code concernant mypackage en un ensemble de fichiers Java qui
peuvent être compilés et qui tournent.
- Dans la section appelée « Collisions », prenez les fragments de code et
transformez les en programme, et vérifiez qu'en fait les collisions arrivent.
- Généralisez la classe P définie dans ce chapitre en ajoutant toutes les
versions surchargées de rint( ) et rintln( )
nécessaires pour gérer tous les types Java de base.
- Modifiez l'instruction import de TestAssert.java pour
autoriser ou inhiber le mécanisme d'assertion.
- Créez une classe avec public, private,
protected, et des membres de données et des méthodes « amicaux ». Faites attention
au fait que des classes dans un même répertoire font partie d'un package « par défaut ».
- Créez une classe avec des données protected. Créez une
deuxième classe dans le même fichier, qui a une méthode qui manipule les données
protected de la première classe.
- Modifiez la classe Cookie comme spécifié dans la section
"protected : sorte d'amical ». Vérifiez que
bite() n'est pas public.
- Dans la section nommée « Accès aux classes » vous trouverez des fragments de
code décrivant mylib etWidget. Créez cette bibliothèque, et
ensuite créez un Widget dans une classe qui ne fait pas partie du package
mylib.
- Créez un nouveau répertoire et modifiez votre CLASSPATH pour inclure ce
nouveau répertoire. Copiez le fichier P.class (produit par la compilation de
com.bruceeckel.tools.P.java) dans votre nouveau répertoire et changez ensuite le
nom du fichier, la classe P à l'intérieur, et les noms de méthodes (vous pouvez
aussi ajouter des sorties supplémentaires pour observer comment cela fonctionne). Créez un autre
programme dans un autre répertoire, qui utilise votre nouvelle classe.
- En suivant la forme de l'exemple Lunch.java, créez une
classe appelée ConnectionManager qui gère un tableau fixe d'objets
Connection. Le programmeur client ne doit pas pouvoir créer explicitement des
objets Connection, mais doit seulement pouvoir les obtenir à l'aide d'une méthode
static dans ConnectionManager. Lorsque le ConnectionManager tombe
à court d'objets, il retourne une référence null. Testez la classe dans
main().
- Créez le fichier suivant dans le répertoire c05/local (supposé être dans
votre CLASSPATH) :
-
|
 |
 |
 |
///: c05:local:PackagedClass.java package c05.local; class PackagedClass { public PackagedClass() { System.out.println( "Creating a packaged class"); } } ///:~
|
 |
///: c05:local:PackagedClass.java package c05.local; class PackagedClass { public PackagedClass() { System.out.println( "Creating a packaged class"); } }///:~
|
 |
 |
 |
Then create the following file in a
directory other than c05:
|
 |
Créez enuite le fichier suivant dans un répertoire autre que c05
:
|
 |
 |
 |
///: c05:foreign:Foreign.java package c05.foreign; import c05.local.*; public class Foreign { public static void main (String[] args) { PackagedClass pc = new PackagedClass(); } } ///:~
|
 |
///: c05:foreign:Foreign.java package c05.foreign; import c05.local.*; public class Foreign { public static void main (String[] args) { PackagedClass pc = new PackagedClass(); } } ///:~
|
 |
 |
 |
Explain why the compiler generates an
error. Would making the Foreign class part of the c05.local
package change anything?
|
 |
Expliquez pourquoi le compilateur génère une erreur. Le fait de mettre la
classe Foreign dans le package c05.local changerait-il quelque
chose ?
|
 |
 |
 |
[32]
There’s nothing in Java that forces the use of an interpreter. There exist
native-code Java compilers that generate a single executable
file.
|
 |
[32] Rien en Java n'oblige à
utiliser un interpréteur. Il existe des compilateurs Java de code natif qui génèrent un seul
fichier exécutable.
|
 |
 |
 |
[33]
There’s another effect in this case: Since the default constructor is the
only one defined, and it’s private, it will prevent inheritance of
this class. (A subject that will be introduced in Chapter 6.)
|
 |
[33] Il y a un autre effet dans
ce cas. Comme le constructeur par défaut est le seul défini, et qu'il est private,
il empêchera l'héritage de cette classe. (Un sujet qui sera présenté dans le Chapitre
6.)
|
 |
 |
 |
[34]
However, people often refer to implementation hiding alone as
encapsulation.
|
 |
[34] Cependant, on parle souvent
aussi d'encapsulation pour le seul fait de cacher l'implémentation.
|
 |
 |
 |
[35]
Actually, an inner class can be private or protected, but that’s a
special case. These will be introduced in Chapter 7.
|
 |
[35] En fait, une classe
interne[inner class] peut être private ou protected, mais il s'agit d'un cas
particulier. Ceux-ci seront présentés au Chapitre 7.
|
 |
 |
 |
[36]
You can also do it by inheriting (Chapter 6) from that class.
|
 |
[36] On peut aussi le faire en
héritant (Chapitre 6) de cette classe.
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |