 |
 |
2) Tout est « objet » |
|
 |
|
Texte original |
 |
Traducteur : Raczy |
|
 |
|
Ce chapitre contient 4 pages
1
2
3
4
|
|
|
 |
 |
 |
 |
 |
 |
|
 |
28.04.2001 - version 1.2 [Armel] - Remise en forme du code html (DIR et PRE en blockquote et pre), Ajout des tags de séparation de pages pour le site (Armel). Suppression des balises TIJ. 02.02.2001 - version 1.1 [Raczy] - Tags + html nettoye 27.06.2000 - version 1.0 [Raczy] - Dernière modification : 27 juin 2000 Traducteur : - Raczy Texte original : -Thinking in Java, 2nd edition, Revision 10 © 2000 by Bruce Eckel
|
 |
 |
 |
2: Everythingis an Object
|
 |
2 : Tout est Objet
|
 |
 |
 |
Although it is based on C++, Java
is more of a “pure” object-oriented language.
|
 |
Bien qu'il soit basé sur C++, Java est un langage orienté objet
plus « pur ».
|
 |
 |
 |
Both C++ and Java are hybrid languages,
but in Java the designers felt that the hybridization was not as important as it
was in C++. A hybrid language allows multiple programming styles; the reason C++
is hybrid is to support backward compatibility with the C language. Because C++
is a superset of the C language, it includes many of that language’s
undesirable features, which can make some aspects of C++ overly
complicated.
|
 |
C++ et Java sont tous les deux des langages hybrides, mais dans Java, les
concepteurs ont pensé que l'hybridation est moins importante qu'elle ne l'est en C++. Un langage
hybride autorise plusieurs styles de programmation : C++ est hybride pour assurer la
compatibilité avec le langage C. Comme C++ est une extension du langage C, il contient un grand
nombre des particularités indésirables de ce langage, ce qui peut rendre certains aspects du C++
particulièrement embrouillés.
|
 |
 |
 |
The Java language assumes that you want
to do only object-oriented programming. This means that before you can begin you
must shift your mindset into an object-oriented world (unless it’s already
there). The benefit of this initial effort is the ability to program in a
language that is simpler to learn and to use than many other OOP languages. In
this chapter we’ll see the basic components of a Java program and
we’ll learn that everything in Java is an object, even a Java
program.
|
 |
Le langage Java suppose qu'on ne veut faire que de la programmation
orientée objet (POO). Ceci signifie qu'avant de pouvoir commencer il faut tourner sa vision des
choses vers un monde orienté objets (à moins qu'elle ne le soit déjà). L'avantage de cet effort
préliminaire est la capacité à programmer dans un langage qui est plus simple à apprendre et à
utiliser que beaucoup d'autres langages de POO. Dans ce chapitre nous verrons les composantes de
base d'un programme Java et nous apprendrons que tout dans Java est objet, même un programme
Java.
|
 |
 |
 |
You manipulate objects with references
|
 |
Les objets sont manipulés avec des références
|
 |
 |
 |
Each programming language has its own
means of manipulating data. Sometimes the programmer must be constantly aware of
what type of manipulation is going on. Are you manipulating the object directly,
or are you dealing with some kind of indirect representation (a pointer in C or
C++) that must be treated with a special syntax?
|
 |
Chaque langage de programmation a ses propres façons de manipuler les
données. Parfois le programmeur doit être constamment conscient du type des manipulations en cours.
Manipulez-vous l'objet directement, ou avez-vous affaire à une sorte de représentation indirecte
(un pointeur en C ou C++) qui doit être traité avec une syntaxe particulière ?
|
 |
 |
 |
All this is simplified in Java. You treat
everything as an object, so there is a single consistent syntax that you use
everywhere. Although you treat everything as an object, the identifier
you manipulate is actually a “reference” to an
object[20]. You
might imagine this scene as a television (the object) with your remote control
(the reference). As long as you’re holding this reference, you have a
connection to the television, but when someone says “change the
channel” or “lower the volume,” what you’re manipulating
is the reference, which in turn modifies the object. If you want to move around
the room and still control the television, you take the remote/reference with
you, not the television.
|
 |
Tout ceci est simplifié en Java. On considère tout comme des objets, ainsi
il n'y a qu'une seule syntaxe cohérente qui est utilisée partout. Bien qu'on traite tout
comme des objets, les identificateurs qui sont manipulés sont en réalité des
« références » vers des objets [21]. On pourrait
imaginer cette situation comme une télévision (l'objet) avec une télécommande (la référence). Tant
qu'on conserve cette référence, on a une liaison vers la télévision, mais quand quelqu'un dit
« change de chaîne » ou « baisse le volume », ce qu'on manipule est la
référence, qui en retour modifie l'objet. Si on veut se déplacer dans la pièce tout en contrôlant
la télévision, on emporte la télécommande/référence, pas la télévision.
|
 |
 |
 |
Also, the remote control can stand on its
own, with no television. That is, just because you have a reference
doesn’t mean there’s necessarily an object connected to it. So if
you want to hold a word or sentence, you create a String
reference:
|
 |
De plus, la télécommande peut exister par elle même sans télévision. C'est
à dire que le fait d'avoir une référence ne signifie pas nécessairement qu'un objet y soit associé.
Ainsi, si on veut avoir avoir un mot ou une phrase, on crée une référence sur une
String :
|
 |
 |
 |
String s;
|
 |
String s;
|
 |
 |
 |
But here you’ve created only the reference, not an object. If you decided to send a message to s at this point, you’ll get an error (at run-time) because s isn’t actually attached to anything (there’s no television). A safer practice, then, is always to initialize a reference when you create it:
|
 |
Mais on a seulement créé la référence, pas un objet. À ce point,
si on décidait d'envoyer un message à s, on aurait une erreur (lors de
l'exécution) parce que s n'est pas rattachée à quoi que ce soit (il n'y a pas de
télévision). Une pratique plus sûre est donc de toujours initialiser une référence quand on la
crée :
|
 |
 |
 |
String s = "asdf";
|
 |
String s = "asdf";
|
 |
 |
 |
However, this uses a special Java feature: strings can be initialized with quoted text. Normally, you must use a more general type of initialization for objects.
|
 |
Toutefois, ceci utilise une caractéristique spéciale de Java : les
chaînes de caractères peuvent être initialisées avec du texte entre guillemets. Normalement, on
doit utiliser un type d'initialisation plus général pour les objets.
|
 |
 |
 |
You must create all the objects
|
 |
Vous devez créer tous les objets
|
 |
 |
 |
When you create a reference, you want to connect it with a new object. You do so, in general, with the new keyword. new says, “Make me a new one of these objects.” So in the above example, you can say:
|
 |
Quand on crée une référence, on veut la connecter à un nouvel objet. Ceci
se fait, en général, avec le mot-clef new. new veut dire
« fabrique moi un de ces objets ». Ainsi, dans l'exemple précédent, on peut
dire :
|
 |
 |
 |
String s = new String("asdf");
|
 |
String s = new String("asdf");
|
 |
 |
 |
Not only does this mean “Make me a new String,” but it also gives information about how to make the String by supplying an initial character string.
|
 |
Ceci ne veut pas seulement dire « fabrique moi un nouvel objet
String », mais cela donne aussi une information sur comment
fabriquer l'objet String en fournissant une chaîne de caractères
initiale.
|
 |
 |
 |
Of course, String is not the only type that exists. Java comes with a plethora of ready-made types. What’s more important is that you can create your own types. In fact, that’s the fundamental activity in Java programming, and it’s what you’ll be learning about in the rest of this book.
|
 |
Bien sûr, String n'est pas le seul type qui existe. Java
propose une pléthore de types tout prêts. Le plus important est qu'on puisse créer ses propres
types. En fait, c'est l'activité fondamentale en programmation Java et c'est ce qu'on apprendra à
faire dans la suite de ce livre.
|
 |
 |
 |
Where storage lives
|
 |
Où réside la mémoire ?
|
 |
 |
 |
It’s useful to visualize some aspects of how things are laid out while the program is running, in particular how memory is arranged. There are six different places to store data:
|
 |
Il est utile de visualiser certains aspects de comment les choses sont
arrangées lorsque le programme tourne, en particulier comment la mémoire est organisée. Il y a six
endroits différents pour stocker les données :
|
 |
 |
 |
-
Registers. This is the fastest storage because it exists in a place different from that of other storage: inside the processor. However, the number of registers is severely limited, so registers are allocated by the compiler according to its needs. You don’t have direct control, nor do you see any evidence in your programs that registers even exist. -
The stack. This lives in the general RAM (random-access memory) area, but has direct support from the processor via its stack pointer. The stack pointer is moved down to create new memory and moved up to release that memory. This is an extremely fast and efficient way to allocate storage, second only to registers. The Java compiler must know, while it is creating the program, the exact size and lifetime of all the data that is stored on the stack, because it must generate the code to move the stack pointer up and down. This constraint places limits on the flexibility of your programs, so while some Java storage exists on the stack—in particular, object references—Java objects themselves are not placed on the stack. -
The heap. This is a general-purpose pool of memory (also in the RAM area) where all Java objects live. The nice thing about the heap is that, unlike the stack, the compiler doesn’t need to know how much storage it needs to allocate from the heap or how long that storage must stay on the heap. Thus, there’s a great deal of flexibility in using storage on the heap. Whenever you need to create an object, you simply write the code to create it using new, and the storage is allocated on the heap when that code is executed. Of course there’s a price you pay for this flexibility: it takes more time to allocate heap storage than it does to allocate stack storage (that is, if you even could create objects on the stack in Java, as you can in C++). -
Static storage. “Static” is used here in the sense of “in a fixed location” (although it’s also in RAM). Static storage contains data that is available for the entire time a program is running. You can use the static keyword to specify that a particular element of an object is static, but Java objects themselves are never placed in static storage. -
Constant storage. Constant values are often placed directly in the program code, which is safe since they can never change. Sometimes constants are cordoned off by themselves so that they can be optionally placed in read-only memory (ROM). -
Non-RAM storage. If data lives completely outside a program it can exist while the program is not running, outside the control of the program. The two primary examples of this are streamed objects, in which objects are turned into streams of bytes, generally to be sent to another machine, and persistent objects, in which the objects are placed on disk so they will hold their state even when the program is terminated. The trick with these types of storage is turning the objects into something that can exist on the other medium, and yet can be resurrected into a regular RAM-based object when necessary. Java provides support for lightweight persistence, and future versions of Java might provide more complete solutions for persistence.
|
 |
- Les registres. C'est le stockage le plus rapide car il se
trouve à un endroit différent des autres zones de stockage : dans le processeur. Toutefois, le
nombre de registres est sévèrement limité, donc les registres sont alloués par le compilateur en
fonction de ses besoins. On n'a aucun contrôle direct et il n'y a même aucune trace de l'existence
des registres dans les programmes.
- La pile. Elle se trouve dans la RAM (random access
memory) mais elle est prise en compte directement par le processeur via son pointeur de
pile. Le pointeur de pile est déplacé vers le bas pour créer plus d'espace mémoire et déplacé
vers le haut pour libérer cet espace. C'est un moyen extrêmement efficace et rapide d'allouer de la
mémoire, supplanté seulement par les registres. Le compilateur Java doit connaître, lorsqu'il crée
le programme, la taille et la durée de vie exacte de toutes les données qui sont rangées sur la
pile, parce qu'il doit générer le code pour déplacer le pointeur de pile vers le haut et vers le
bas. Cette contrainte met des limites à la flexibilité des programmes, donc, bien qu'il y ait du
stockage Java sur la pile -- en particulier les références aux objets -- les objets Java eux même
ne sont pas placés sur la pile.
- Le segment. C'est une réserve de mémoire d'usage général
(aussi en RAM) où résident tous les objets java. La bonne chose à propos du segment est que,
contrairement à la pile, le compilateur n'a pas besoin de savoir de combien de place il a besoin
d'allouer sur le segment ni combien de temps cette place doit rester sur le segment.Ainsi, il y a
une grande flexibilité à utiliser la mémoire sur le segment. Lorsqu'on a besoin de créer un objet,
il suffit d'écrire le code pour le créer en utilisant new et la mémoire est
allouée sur le segment lorsque le programme s'exécute. Bien entendu il y a un prix à payer pour
cette flexibilité : il faut plus de temps pour allouer de la mémoire sur le segment qu'il n'en
faut pour allouer de la mémoire sur la pile (c'est à dire si on avait la possibilité de
créer des objets sur la pile en Java, comme on peut le faire en C++).
- La mémoire statique. « Statique » est utilisé
ici dans le sens « à un endroit fixe » (bien que ce soit aussi dans la RAM). La mémoire
statique contient les données qui sont disponibles pendant tout le temps d'exécution du programme.
On peut utiliser le mot-clef static pour spécifier qu'un élément particulier d'un
objet est statique, mais les objets Java par eux-mêmes ne sont jamais placés dans la mémoire
statique.
- Les constantes. Les valeurs des constantes sont souvent
placées directement dans le code du programme, ce qui est sûr puisqu'elles ne peuvent jamais
changer. Parfois les constantes sont isolées de façon à pouvoir être optionnellement placées dans
une mémoire accessible en lecture seulement (ROM).
- Stockage hors RAM. Si les données résident entièrement
hors du programme, elles peuvent exister même quand le programme ne tourne pas, en dehors du
contrôle du programme. Les deux exemples de base sont les flots de données, pour lesquels
les données sont transformées en flots d'octets, généralement pour être transmises vers une autre
machine, et les objets persistants, pour lesquels les objets sont placés sur disque de
façon à ce qu'ils conservent leur état même après que le programme soit terminé. L'astuce avec ces
types de stockage est de transformer les objets en quelque chose qui peut exister sur l'autre
support, tout en pouvant être ressuscité en un objet normal en mémoire, lorsque c'est nécessaire.
Java fournit des outils pour la persistance légère, et les versions futures pourraient
fournir des solutions plus complètes pour la persistance.
|
 |
 |
 |
Special case: primitive types
|
 |
Cas particulier : les types primitifs
|
 |
 |
 |
There is a group of types that gets special treatment; you can think of these as “primitive” types that you use quite often in your programming. The reason for the special treatment is that to create an object with new—especially a small, simple variable—isn’t very efficient because new places objects on the heap. For these types Java falls back on the approach taken by C and C++. That is, instead of creating the variable using new, an “automatic” variable is created that is not a reference. The variable holds the value, and it’s placed on the stack so it’s much more efficient.
|
 |
Il y a un ensemble de types qui sont soumis à un traitement
particulier ; ils peuvent être considérés comme les types « primitifs » fréquemment
utilisés en programmation. La raison de ce traitement particulier est que la création d'un objet
avec new -- en particulier une simple variable -- n'est pas très efficace parce
que new place les objets sur le segment. Pour ces types, Java a recours à
l'approche retenue en C et en C++. Au lieu de créer la variable en utilisant new,
une variable « automatique », qui n'est pas une référence, est créée. La variable
contient la valeur et elle est placée sur la pile, ce qui est beaucoup plus efficace.
|
 |
 |
 |
Java determines the size of each primitive type. These sizes don’t change from one machine architecture to another as they do in most languages. This size invariance is one reason Java programs are so portable.
|
 |
Java fixe la taille de chacun des types primitifs. Ces tailles ne changent
pas d'une architecture de machine à une autre, comme c'est le cas dans la plupart des langages.
L'invariance de la taille de ces types est l'une des raisons pour lesquelles Java est si
portable.
|
 |
 |
 |
Primitive type | Size | Minimum | Maximum | Wrapper type | boolean | — | — | — | Boolean | char | 16-bit | Unicode 0 | Unicode 216- 1 | Character | byte | 8-bit | -128 | +127 | Byte | short | 16-bit | -215 | +215—1 | Short | int | 32-bit | -231 | +231—1 | Integer | long | 64-bit | -263 | +263—1 | Long | float | 32-bit | IEEE754 | IEEE754 | Float | double | 64-bit | IEEE754 | IEEE754 | Double | void | — | — | — | Void |
|
 |
Type primitif |
Taille |
Minimum |
Maximum |
Type wrapper |
boolean |
- |
- |
- |
Boolean |
char |
16-bit |
Unicode 0 |
Unicode 216- 1 |
Character |
byte |
8-bit |
-128 |
+127 |
Byte |
short |
16-bit |
-215 |
+215-1 |
Short |
int |
32-bit |
-231 |
+231-1 |
Integer |
long |
64-bit |
-263 |
+263-1 |
Long |
float |
32-bit |
IEEE754 |
IEEE754 |
Float |
double |
64-bit |
IEEE754 |
IEEE754 |
Double |
void |
- |
- |
- |
Void |
|
 |
 |
 |
All numeric types are signed, so don’t go looking for unsigned types.
|
 |
Tous les types numériques sont signés, il est donc inutile d'aller chercher
après des types non signés.
|
 |
 |
 |
The size of the boolean type is not explicitly defined; it is only specified to be able to take the literal values true or false.
|
 |
|
 |
 |
 |
The primitive data types also have “wrapper” classes for them. That means that if you want to make a nonprimitive object on the heap to represent that primitive type, you use the associated wrapper. For example:
|
 |
Les types de données primitifs sont aussi associés à des classes
« wrapper ». Ceci signifie que pour faire un objet non primitif sur le segment pour
représenter ce type primitif il faut utiliser le wrapper associé. Par exemple :
|
 |
 |
 |
char c = 'x'; Character C = new Character(c);
|
 |
char c = 'x';Character C = new Character(c);
|
 |
 |
 |
Or you could also use:
|
 |
On peut aussi utiliser :
|
 |
 |
 |
Character C = new Character('x');
|
 |
Character C = new Character('x');
|
 |
 |
 |
The reasons for doing this will be shown in a later chapter.
|
 |
Les raisons pour lesquelles on fait ceci seront indiquées dans un prochain
chapitre.
|
 |
 |
 |
High-precision numbers
|
 |
Nombres de grande précision
|
 |
 |
 |
Java includes two classes for performing high-precision arithmetic: BigInteger and BigDecimal. Although these approximately fit into the same category as the “wrapper” classes, neither one has a primitive analogue.
|
 |
Java contient deux classes pour effectuer des opérations arithmétiques de
grande précision : BigInteger et BigDecimal. Bien que
ceux-ci soient dans la même catégorie que les classes « wrapper », aucun d'eux n'a
d'analogue primitif.
|
 |
 |
 |
Both classes have methods that provide analogues for the operations that you perform on primitive types. That is, you can do anything with a BigInteger or BigDecimal that you can with an int or float, it’s just that you must use method calls instead of operators. Also, since there’s more involved, the operations will be slower. You’re exchanging speed for accuracy.
|
 |
Chacune de ces classes a des méthodes qui fournissent des opérations
analogues à celles qu'on peut faire sur les types primitifs. C'est à dire qu'avec un
BigInteger ou un BigDecimal on peut faire tout ce qu'on peut
faire avec un int ou un float, seulement il faut utiliser des
appels de méthodes au lieu des opérateurs. Par ailleurs, comme elles en font plus, les opérations
sont plus lentes. On échange la vitesse contre la précision.
|
 |
 |
 |
BigInteger supports arbitrary-precision integers. This means that you can accurately represent integral values of any size without losing any information during operations.
|
 |
BigInteger sert aux entiers de précision arbitraire. C'est
à dire qu'ils permettent de représenter des valeurs entières de n'importe quelle taille sans perdre
aucune information au cours des opérations.
|
 |
 |
 |
BigDecimal is for arbitrary-precision fixed-point numbers; you can use these for accurate monetary calculations, for example.
|
 |
BigDecimal sert aux nombres à virgule fixe de précision
arbitraire ; par exemple, on peut les utiliser pour des calculs monétaires précis.
|
 |
 |
 |
Consult your online documentation for details about the constructors and methods you can call for these two classes.
|
 |
Il faut se reporter à la documentation en ligne pour obtenir des détails
sur les constructeurs et méthodes utilisables avec ces deux classes.
|
 |
 |
 |
Arrays in Java
|
 |
Tableaux en Java
|
 |
 |
 |
Virtually all programming languages support arrays. Using arrays in C and C++ is perilous because those arrays are only blocks of memory. If a program accesses the array outside of its memory block or uses the memory before initialization (common programming errors) there will be unpredictable results.
|
 |
Pratiquement tous les langages de programmation gèrent les tableaux.
Utiliser des tableaux en C ou C++ est dangereux car ces tableaux ne sont que des blocs de mémoire.
Si un programme accède à un tableau en dehors de son bloc mémoire, ou s'il utilise la mémoire avant
initialisation (erreurs de programmation fréquentes) les résultats seront imprévisibles.
|
 |
 |
 |
One of the primary goals of Java is safety, so many of the problems that plague programmers in C and C++ are not repeated in Java. A Java array is guaranteed to be initialized and cannot be accessed outside of its range. The range checking comes at the price of having a small amount of memory overhead on each array as well as verifying the index at run-time, but the assumption is that the safety and increased productivity is worth the expense.
|
 |
Un des principaux objectifs de Java est la sécurité, aussi, un grand nombre
des problèmes dont souffrent C et C++ ne sont pas répétés en Java. On est assuré qu'un tableau Java
est initialisé et qu'il ne peut pas être accédé en dehors de ses bornes. La vérification des bornes
se fait au prix d'un petit excédent de mémoire pour chaque tableau ainsi que de la vérification de
l'index lors de l'exécution, mais on suppose que le gain en sécurité et en productivité vaut la
dépense.
|
 |
 |
 |
When you create an array of objects, you are really creating an array of references, and each of those references is automatically initialized to a special value with its own keyword: null. When Java sees null, it recognizes that the reference in question isn’t pointing to an object. You must assign an object to each reference before you use it, and if you try to use a reference that’s still null, the problem will be reported at run-time. Thus, typical array errors are prevented in Java.
|
 |
Quand on crée un tableau d'objets, on crée en réalité un tableau de
références, et chacune de ces références est automatiquement initialisée à une valeur particulière
avec son propre mot clé : null. Quand Java voit null, il
reconnaît que la référence en question ne pointe pas vers un objet. Il faut affecter un objet à
chaque référence avant de l'utiliser et si on essaye d'utiliser une référence encore à
null, le problème sera signalé lors de l'exécution. Ainsi, les erreurs typiques
sur les tableaux sont évitées en Java.
|
 |
 |
 |
You can also create an array of primitives. Again, the compiler guarantees initialization because it zeroes the memory for that array.
|
 |
On peut aussi créer des tableaux de variables de type primitif. À nouveau,
le compilateur garantit l'initialisation car il met à zéro la mémoire utilisée par ces
tableaux.
|
 |
 |
 |
Arrays will be covered in detail in later chapters.
|
 |
Les tableaux seront traités plus en détails dans d'autres
chapitres.
|
 |
 |
 |
You never need to destroy an object
|
 |
Vous n'avez jamais besoin de détruire un objet
|
 |
 |
 |
In most programming languages, the concept of the lifetime of a variable occupies a significant portion of the programming effort. How long does the variable last? If you are supposed to destroy it, when should you? Confusion over variable lifetimes can lead to a lot of bugs, and this section shows how Java greatly simplifies the issue by doing all the cleanup work for you.
|
 |
Dans la plupart des langages de programmation, le concept de durée de vie
d'une variable monopolise une part significative des efforts de programmation. Combien de temps une
variable existe-t-elle ? S'il faut la détruire, quand faut-il le faire ? Des erreurs sur
la durée de vie des variables peuvent être la source de nombreux bugs et cette partie montre
comment Java simplifie énormément ce problème en faisant le ménage tout seul.
|
 |
 |
 |
Scoping
|
 |
Notion de portée
|
 |
 |
 |
Most procedural languages have the concept of scope. This determines both the visibility and lifetime of the names defined within that scope. In C, C++, and Java, scope is determined by the placement of curly braces {}. So for example:
|
 |
La plupart des langages procéduraux ont le concept de portée. Il
fixe simultanément la visibilité et la durée de vie des noms définis dans cette portée. En C, C++
et Java, la portée est fixée par l'emplacement des accolades {}. Ainsi, par
exemple :
|
 |
 |
 |
{ int x = 12; /* only x available */ { int q = 96; /* both x & q available */ } /* only x available */ /* q “out of scope” */ }
|
 |
{ int x = 12; /* seul x est accessible */ { int q = 96; /* x & q sont tous les deux accessibles */ } /* seul x est accessible */ /* q est « hors de portée » */ }
|
 |
 |
 |
A variable defined within a scope is
available only to the end of that scope.
|
 |
Une variable définie dans une portée n'est accessible que jusqu'à la fin de
cette portée.
|
 |
 |
 |
Indentation makes Java code easier to
read. Since Java is a free-form language, the extra spaces, tabs, and carriage
returns do not affect the resulting program.
|
 |
L'indentation rend le code Java plus facile à lire. Étant donné que Java
est un langage indépendant de la mise en page, les espaces, tabulations et retours chariots
supplémentaires ne changent pas le programme.
|
 |
 |
 |
Note that you cannot do the
following, even though it is legal in C and C++:
|
 |
Il faut remarquer qu'on ne peut pas faire la chose suivante, bien que cela
soit autorisé en C et C++ :
|
 |
 |
 |
{ int x = 12; { int x = 96; /* illegal */ } }
|
 |
{ int x = 12; { int x = 96; /* illegal */ } }
|
 |
 |
 |
The compiler will announce that the
variable x has already been defined. Thus the C and C++ ability to
“hide” a variable in a larger scope is not allowed because the Java
designers thought that it led to confusing
programs.
|
 |
Le compilateur annoncera que la variable x a déjà été
définie. Ainsi, la faculté du C et du C++ à « cacher » une variable d'une portée plus
étendue n'est pas autorisée parce que les concepteurs de Java ont pensé que ceci mène à des
programmes confus.
|
 |
 |
 |
Scope of objects
|
 |
Portée des objets
|
 |
 |
 |
Java objects do not have the same
lifetimes as primitives. When you create a Java object using new, it
hangs around past the end of the scope. Thus if you use:
|
 |
Les objets Java n'ont pas la même durée de vie que les variables
primitives. Quand on crée un objet Java avec new, il existe toujours après la fin
de la portée. Ainsi, si on fait :
|
 |
 |
 |
{ String s = new String("a string"); } /* end of scope */
|
 |
{ String s = new String("a string"); } /* fin de portée */
|
 |
 |
 |
the reference s vanishes at the
end of the scope. However, the String object that s was pointing
to is still occupying memory. In this bit of code, there is no way to access the
object because the only reference to it is out of scope. In later chapters
you’ll see how the reference to the object can be passed around and
duplicated during the course of a program.
|
 |
la référence s disparaît à la fin de la portée. Par contre
l'objet String sur lequel s pointait occupe toujours la mémoire.
Dans ce bout de code, il n'y a aucun moyen d'accéder à l'objet parce que son unique référence est
hors de portée. Dans d'autres chapitres on verra comment la référence à un objet peut être
transmise et dupliquée dans un programme.
|
 |
 |
 |
It turns out that because objects created
with new stay around for as long as you want them, a whole slew of C++
programming problems simply vanish in Java. The hardest problems seem to occur
in C++ because you don’t get any help from the language in making sure
that the objects are available when they’re needed. And more important, in
C++ you must make sure that you destroy the objects when you’re done with
them.
|
 |
Il s'avère que du simple fait qu'un objet créé avec new reste disponible
tant qu'on le veut, tout un tas de problèmes de programmation du C++ disparaissent tout simplement
en Java. Il semble que les problèmes les plus durs surviennent en C++ parce que le langage ne
fournit aucune aide pour s'assurer que les objets sont disponibles quand on en a besoin. Et, encore
plus important, en C++ on doit s'assurer qu'on détruit bien les objets quand on en a terminé avec
eux.
|
 |
 |
 |
That brings up an interesting question.
If Java leaves the objects lying around, what keeps them from filling up memory
and halting your program? This is exactly the kind of problem that would occur
in C++. This is where a bit of magic happens. Java has a garbage
collector, which looks at all the objects that were created with new
and figures out which ones are not being referenced anymore. Then it releases
the memory for those objects, so the memory can be used for new objects. This
means that you never need to worry about reclaiming memory yourself. You simply
create objects, and when you no longer need them they will go away by
themselves. This eliminates a certain class of programming problem: the
so-called “memory leak,” in which a programmer forgets to release
memory.
|
 |
Ceci amène une question intéressante. Si Java laisse les objets traîner,
qu'est-ce qui les empêche de complètement remplir la mémoire et d'arrêter le programme ? C'est
exactement le problème qui surviendrait dans un programme C++. C'est là qu'un peu de magie
apparaît. Java a un ramasse-miettes qui surveille tous les objets qui ont été créés avec
new et qui arrive à deviner lesquels ne sont plus référencés. Ensuite il libère la
mémoire de ces objets de façon à ce que cette mémoire puisse être utilisée pour de nouveaux objets.
Ceci signifie qu'il ne faut jamais s'embêter à récupérer la mémoire soi-même. On crée simplement
les objets, et quand on n'en a plus besoin, ils disparaissent d'eux même. Ceci élimine toute une
classe de problèmes de programmation : les soi-disant « fuites de mémoire » qui
arrivent quand un programmeur oublie de libérer la mémoire.
|
 |
 |
 |
Creating new data types: class
|
 |
Créer de nouveaux types de données : class
|
 |
 |
 |
If everything is an object, what
determines how a particular class of object looks and behaves? Put another way,
what establishes the type of an object? You might expect there to be a
keyword called “type,” and that certainly would have made sense.
Historically, however, most object-oriented languages have used the keyword
class to mean “I’m about to tell you what a new type of
object looks like.” The class keyword (which is so common that it
will not be emboldened throughout this book) is followed by the name of the new
type. For example:
|
 |
Si tout est objet, qu'est-ce qui définit à quoi ressemble une classe
particulière d'objets et comment elle se comporte ? Autrement dit, qu'est-ce qui constitue le
type d'un objet ? On pourrait s'attendre à avoir un mot-clef appelé
« type », et cela serait parfaitement sensé. Historiquement, toutefois, la plupart des
langages orientés objet ont utilisé le mot-clef class qui signifie « je vais
décrire à quoi ressemble un nouveau type d'objet ». Le mot-clef class (qui
est si commun qu'il ne sera plus mis en gras dans la suite de ce livre) est suivi par le nom du
nouveau type. Par exemple :
|
 |
 |
 |
class ATypeName { /* class body goes here */ }
|
 |
class ATypeName { /* le corps de la classe vient ici */ }
|
 |
 |
 |
This introduces a new type, so you can now create an object of this type using new:
|
 |
Ceci introduit un nouveau type, on peut alors créer un objet de ce type en
utilisant new :
|
 |
 |
 |
ATypeName a = new ATypeName();
|
 |
ATypeName a = new ATypeName();
|
 |
 |
 |
In ATypeName, the class body consists only of a comment (the stars and slashes and what is inside, which will be discussed later in this chapter), so there is not too much that you can do with it. In fact, you cannot tell it to do much of anything (that is, you cannot send it any interesting messages) until you define some methods for it.
|
 |
Dans ATypeName, le corps de la classe ne consiste qu'en un
commentaire (les étoiles et barres obliques et ce qu'il y a à l'intérieur, ce qui sera décrit
ultérieurement dans ce chapitre), donc il n'y pas grand chose à faire avec. En fait, on ne peut pas
lui dire de faire quoi que ce soit (c'est à dire qu'on ne peut pas lui transmettre de message
intéressant) tant qu'on n'y définit pas de méthodes.
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |