 |
 |
1) Introduction sur les ? objets ? |
|
 |
|
Texte original |
 |
Traducteur : J?ome QUELIN |
|
 |
|
Ce chapitre contient 8 pages
1
2
3
4
5
6
7
8
|
|
|
 |
 |
 |
 |
 |
 |
|
 |
02.12.2001 -version 5.9.1 [Armel] : - Enlev l'encodage ? latin-1 ? lors du passage dans html-tidy - Ajout de deux, trois balises font manquantes. 02.12.2001 - version 5.9 [Jérome] : - Corrections apportées par Patrick Godeau. 22.06.2001 - version 5.8 : - Ajout des tags de séparation de pages pour le site (Armel). 28.04.2001 - version 5.7 : - Remise en forme du code html [Armel avec HTML-Kit], balises font, a... 04.08.2000 - version 5.6 : - Corrections apportées par Daniel Le Berre 26.06.2000 - version 5.5 : - Insertion du journal de log. 18.06.2000 - version 5.4 : - Modification des tags {url: http:// www.blahblah.com} en www.blahblah.com. - "langage de scripting" modifié en "langage de script". - Modification des guillemets "" en «». 06.06.2000 - version 5.3 : - Corrections apportées par Philippe Boîte. 05.06.2000 - version 5.2 : - Corrections apportées par Jean-Pierre Vidal. 02.06.2000 - version 5.1 : - Première publication sur eGroups. Traducteur : - Jérome QUELIN Texte original : - Thinking in Java, 2nd edition, Revision 10 © 2000 by Bruce ECKEL
|
 |
 |
 |
1: Introduction to Objects
|
 |
1) Introduction sur les Objets
|
 |
 |
 |
The genesis of the computer
revolution was in a machine. The genesis of our programming languages thus tends
to look like that machine.
|
 |
La révolution informatique a pris naissance dans une
machine. Nos langages de programmation ont donc tendance à ressembler à cette
machine.
|
 |
 |
 |
But computers are not so much machines as
they are mind amplification tools (“bicycles for the mind,” as Steve
Jobs is fond of saying) and a different kind of expressive medium. As a result,
the tools are beginning to look less like machines and more like parts of our
minds, and also like other forms of expression such as writing, painting,
sculpture, animation, and filmmaking. Object-oriented programming (OOP) is part
of this movement toward using the computer as an expressive
medium.
|
 |
Mais les ordinateurs ne sont pas tant des machines que des outils au
service de l'esprit (« des vélos pour le cerveau », comme aime
à le répéter Steve Jobs) et un nouveau moyen d'expression. Ainsi, ces outils
commencent à moins ressembler à des machines et plus à des parties de notre
cerveau ou d'autres formes d'expressions telles que l'écriture, la peinture, la sculpture ou
la réalisation de films. La Programmation Orientée Objet (POO) fait partie de ce
mouvement qui utilise l'ordinateur en tant que moyen d'expression.
|
 |
 |
 |
This chapter will introduce you to the
basic
concepts of OOP, including an overview of development methods. This chapter, and
this book, assume that you have had experience in a
procedural programming language, although not necessarily C. If you think you
need more preparation in programming and the syntax of C before tackling this
book, you should work through the Thinking in C: Foundations for C++ and
Java training CD ROM, bound in with this book and also available at
www.BruceEckel.com.
|
 |
Ce chapitre présente les concepts de base de la POO, y compris
quelques méthodes de développement. Ce chapitre et ce livre présupposent
que vous avez déjà expérimenté avec un langage de programmation
procédural, bien que celui-ci ne soit pas forcément le C. Si vous pensez que vous
avez besoin de plus de pratique dans la programmation et / ou la syntaxe du C avant de commencer ce
livre, vous devriez explorer le CD ROM fourni avec le livre, Thinking in C: Foundations for C++
and Java, aussi disponible sur www.BruceEckel.com.
|
 |
 |
 |
This chapter is background and
supplementary material. Many people do not feel comfortable wading into
object-oriented programming without understanding the big picture first. Thus,
there are many concepts that are introduced here to give you a solid overview of
OOP. However, many other people don’t get the big picture concepts until
they’ve seen some of the mechanics first; these people may become bogged
down and lost without some code to get their hands on. If you’re part of
this latter group and are eager to get to the specifics of the language, feel
free to jump past this chapter—skipping it at this point will not prevent
you from writing programs or learning the language. However, you will want to
come back here eventually to fill in your knowledge so you can understand why
objects are important and how to design with
them.
|
 |
Ce chapitre tient plus de la culture générale. Beaucoup de
personnes ne veulent pas se lancer dans la programmation orientée objet sans en comprendre
d'abord les tenants et les aboutissants. C'est pourquoi nous allons introduire ici de nombreux
concepts afin de vous donner un solide aperçu de la POO. Au contraire, certaines personnes
ne saisissent les concepts généraux qu'après en avoir vu quelques
mécanismes mis en œuvre ; ces gens-là se sentent perdus s'ils n'ont pas un
bout de code à se mettre sous la dent. Si vous faites partie de cette catégorie de
personnes et êtes impatients d'attaquer les spécificités du langage, vous
pouvez sauter ce chapitre - cela ne vous gênera pas pour l'écriture de programme ou
l'apprentissage du langage. Mais vous voudrez peut-être y revenir plus tard pour approfondir
vos connaissances sur les objets, les comprendre et assimiler la conception objet.
|
 |
 |
 |
The progress of abstraction
|
 |
Les bienfaits de l'abstraction
|
 |
 |
 |
All programming languages provide
abstractions. It can be argued that the complexity of the problems you’re
able to solve is directly related to the kind and quality of
abstraction. By “kind” I mean, “What is
it that you are abstracting?” Assembly language is a small abstraction of
the underlying machine. Many so-called “imperative” languages that
followed (such as Fortran, BASIC, and C) were abstractions of assembly language.
These languages are big improvements over assembly language, but their primary
abstraction still requires you to think in terms of the structure of the
computer rather than the structure of the problem you are trying to solve. The
programmer must establish the association between the machine model (in the
“solution space,” which
is the place where you’re modeling that problem, such as a computer) and
the model of the problem that is actually being solved (in the
“problem space,” which
is the place where the problem exists). The effort required to perform this
mapping, and the fact that it is extrinsic to the programming language, produces
programs that are difficult to write and expensive to maintain, and as a side
effect created the entire “programming methods”
industry.
|
 |
Tous les langages de programmation fournissent des abstractions. On peut
dire que la complexité des problèmes qu'on est capable de résoudre est
directement proportionnelle au type et à la qualité de nos
capacités d'abstraction. Par « type », il faut comprendre
« Qu'est-ce qu'on tente d'abstraire ? ». Le langage assembleur est une
petite abstraction de la machine sous-jacente. Beaucoup de langages « impératifs
» (tels que Fortran, BASIC, et C) sont des abstractions du langage assembleur. Ces langages
sont de nettes améliorations par rapport à l'assembleur, mais leur abstraction
première requiert une réflexion en termes de structure ordinateur plutôt
qu'à la structure du problème qu'on essaye de résoudre. Le programmeur doit
établir l'association entre le modèle de la machine (dans « l'espace
solution », qui est l'endroit où le problème est modélisé,
tel que l'ordinateur) et le modèle du problème à résoudre (dans
« l'espace problème », qui est l'endroit où se trouve le
problème). Les efforts requis pour réaliser cette association, et le fait qu'elle est
étrangère au langage de programmation, produit des programmes difficiles à
écrire et à maintenir, et comme effet de bord a mené à la
création de l'industrie du « Génie Logiciel».
|
 |
 |
 |
The alternative to modeling the machine
is to model the problem you’re trying to solve. Early languages such as
LISP and APL chose particular views of the world (“All problems are
ultimately lists” or “All problems are algorithmic,”
respectively). PROLOG casts all problems into chains of decisions. Languages
have been created for constraint-based programming and for programming
exclusively by manipulating graphical symbols. (The latter proved to be too
restrictive.) Each of these approaches is a good solution to the particular
class of problem they’re designed to solve, but when you step outside of
that domain they become awkward.
|
 |
L'autre alternative à la modélisation de la machine est de
modéliser le problème qu'on tente de résoudre. Les premiers langages tels que
LISP ou APL choisirent une vue particulière du monde (« Tous les problèmes
se ramènent à des listes » ou « Tous les problèmes sont
algorithmiques », respectivement). PROLOG convertit tous les problèmes en
chaînes de décisions. Des langages ont été créés en vue de
programmer par contrainte, ou pour programmer en ne manipulant que des symboles graphiques (ces
derniers se sont révélés être trop restrictifs). Chacune de ces
approches est une bonne solution pour la classe particulière de problèmes pour
laquelle ils ont été conçus, mais devient une horreur dès lors que vous
les sortez de leur domaine d'application.
|
 |
 |
 |
The object-oriented approach goes a step
further by providing tools for the programmer to represent elements in the
problem space. This representation is general enough that the programmer is not
constrained to any particular type of problem. We refer to the elements in the
problem space and their representations in the solution space
as “objects.” (Of course, you will also need
other objects that don’t have problem-space analogs.) The idea is that the
program is allowed to adapt itself to the lingo of the problem by adding new
types of objects, so when you read the code describing the solution,
you’re reading words that also express the problem. This is a more
flexible and powerful language abstraction than what we’ve had before.
Thus, OOP allows you to describe the problem in terms of the problem, rather
than in terms of the computer where the solution will run. There’s still a
connection back to the computer, though. Each object looks quite a bit like a
little computer; it has a state, and it has operations that you can ask it to
perform. However, this doesn’t seem like such a bad analogy to objects in
the real world—they all have characteristics and behaviors.
|
 |
L'approche orientée objet va un cran plus loin en fournissant des
outils au programmeur pour représenter des éléments dans l'espace
problème. Cette représentation se veut assez générale pour ne pas
restreindre le programmeur à un type particulier de problèmes. Nous nous
référons aux éléments dans l'espace problème et leur
représentation dans l'espace solution en tant qu'« objets ». (Bien
sûr, on aura aussi besoin d'autres objets qui n'ont pas leur analogue dans l'espace
problème). L'idée est que le programme est autorisé à s'adapter
à l'esprit du problème en ajoutant de nouveaux types d'objet, de façon
à ce que, quand on lit le code décrivant la solution, on lit aussi quelque chose qui
décrit le problème. C'est une abstraction plus flexible et puissante que tout ce
qu'on a pu voir jusqu'à présent. Ainsi, la POO permet de décrire le
problème avec les termes mêmes du problème plutôt qu'avec les termes de
la machine où la solution sera mise en oeuvre. Il y a tout de même une connexion avec
l'ordinateur, bien entendu. Chaque objet ressemble à un mini-ordinateur ; il a un
état, et il a à sa disposition des opérations qu'on peut lui demander
d'exécuter. Cependant, là encore on retrouve une analogie avec les objets du monde
réel - ils ont tous des caractéristiques et des comportements.
|
 |
 |
 |
Some language designers have decided that
object-oriented programming by itself is not adequate to easily solve all
programming problems, and advocate the combination of various approaches into
multiparadigm programming
languages.[2]
|
 |
Des concepteurs de langage ont décrété que la
programmation orientée objet en elle-même n'était pas adéquate pour
résoudre facilement tous les problèmes de programmation, et recommandent la
combinaison d'approches variées dans des langages de programmation
multiparadigmes.[2]
|
 |
 |
 |
Alan Kay summarized five
basic characteristics of Smalltalk,
the first successful object-oriented language and one of the languages upon
which Java is based. These characteristics represent a pure approach to
object-oriented
programming:
|
 |
Alan Kay résume les cinq caractéristiques principales de
Smalltalk, le premier véritable langage de programmation orienté objet et l'un des
langages sur lequel est basé Java. Ces caractéristiques représentent une
approche purement orientée objet :
|
 |
 |
 |
- Everything is an
object. Think of an object as a fancy variable;
it stores data, but you can “make requests” to that object, asking
it to perform operations on itself. In theory, you can take any conceptual
component in the problem you’re trying to solve (dogs, buildings,
services, etc.) and represent it as an object in your
program.
- A program is a bunch of objects
telling each other what to do by sending
messages. To make a request of an object, you
“send a message” to that object. More concretely, you can think of a
message as a request to call a function that belongs to a particular
object.
- Each object has its own memory made
up of other objects. Put another way, you create
a new kind of object by making a package containing existing objects. Thus, you
can build complexity in a program while hiding it behind the simplicity of
objects.
- Every object has a
type. Using the parlance, each object is an
instance of a class, in which “class” is synonymous
with “type.” The most important distinguishing characteristic of a
class is “What messages can you send to
it?”
- All objects of a particular type
can receive the same messages. This is actually
a loaded statement, as you will see later. Because an object of type
“circle” is also an object of type “shape,” a circle is
guaranteed to accept shape messages. This means you can write code that talks to
shapes and automatically handle anything that fits the description of a shape.
This substitutability is one of the most powerful concepts in
OOP.
|
 |
- Toute chose est un objet. Il faut penser à un
objet comme à une variable améliorée : il stocke des données, mais
on peut « effectuer des requêtes » sur cet objet, lui demander de faire
des opérations sur lui-même. En théorie, on peut prendre n'importe quel
composant conceptuel du problème qu'on essaye de résoudre (un chien, un immeuble, un
service administratif, etc...) et le représenter en tant qu'objet dans le
programme.
- Un programme est un ensemble d'objets se disant les uns aux autres
quoi faire en s'envoyant des messages. Pour qu'un objet effectue une requête, on
« envoie un message » à cet objet. Plus concrètement, on peut
penser à un message comme à un appel de fonction appartenant à un objet
particulier.
- Chaque objet a son propre espace de mémoire composé
d'autres objets. Dit d'une autre manière, on crée un nouveau type d'objet en
créant un paquetage contenant des objets déjà existants. Ainsi, la
complexité d'un programme est cachée par la simplicité des objets mis en
oeuvre.
- Chaque objet est d'un type précis. Dans le jargon
de la POO, chaque objet est une instance d'une classe, où
« classe » est synonyme de « type ». La plus importante
caractéristique distinctive d'une classe est : « Quels messages peut-on lui
envoyer ? ».
- Tous les objets d'un type particulier peuvent recevoir le
même message. C'est une caractéristique lourde de signification, comme vous
le verrez plus tard. Parce qu'un objet de type « cercle » est aussi un objet de
type « forme géométrique », un cercle se doit d'accepter les
messages destinés aux formes géométriques. Cela veut dire qu'on peut
écrire du code parlant aux formes géométriques qui sera accepté par
tout ce qui correspond à la description d'une forme géométrique. Cette
substituabilité est l'un des concepts les plus puissants de la programmation
orientée objet.
|
 |
 |
 |
An object has an interface
|
 |
Un objet dispose d'une interface
|
 |
 |
 |
Aristotle was probably the first to begin
a careful study of the concept of type; he spoke of “the class of
fishes and the class of birds.” The idea that all objects, while being
unique, are also part of a class of objects that have characteristics and
behaviors in common was used directly in the first object-oriented language,
Simula-67, with its fundamental keyword class that introduces a new type
into a program.
|
 |
Aristote fut probablement le premier à commencer une étude
approfondie du concept de type ; il parle de « la classe des poissons et la
classe des oiseaux ». L'idée que tous les objets, tout en étant uniques,
appartiennent à une classe d'objets qui ont des caractéristiques et des comportements
en commun fut utilisée directement dans le premier langage orienté objet, Simula-67,
avec son mot clef fondamental class qui introduit un nouveau type dans un
programme.
|
 |
 |
 |
Simula,
as its name implies, was created for developing simulations such as the classic
“bank teller problem.” In this, you have a bunch of tellers,
customers, accounts, transactions, and units of money—a lot of
“objects.” Objects that are identical except for their state during
a program’s execution are grouped together into “classes of
objects” and that’s where the
keyword class came from.
Creating abstract data types (classes) is a fundamental concept in
object-oriented programming. Abstract data types work almost exactly like
built-in types: You can create variables of a type (called objects or
instances in object-oriented parlance) and manipulate those variables
(called sending messages or
requests; you send a message and the object figures
out what to do with it). The members (elements) of each class share some
commonality: every account has a balance, every teller can accept a deposit,
etc. At the same time, each member has its own state, each account has a
different balance, each teller has a name. Thus, the tellers, customers,
accounts, transactions, etc., can each be represented with a unique entity in
the computer program. This entity is the object, and each object belongs to a
particular class that defines its characteristics and
behaviors.
|
 |
Simula, comme son nom l'indique, a été conçu pour
développer des simulations telles qu'un guichet de banque. Dans celle-ci, vous avez un
ensemble de guichetiers, de clients, de comptes, de transactions et de devises - un tas
« d'objets ». Des objets semblables, leur état durant
l'exécution du programme mis à part, sont groupés ensemble en tant que
« classes d'objets » et c'est de là que vient le mot clef
class. Créer des types de données abstraits (des classes) est un
concept fondamental dans la programmation orientée objet. On utilise les types de
données abstraits exactement de la même manière que les types de données
prédéfinis. On peut créer des variables d'un type particulier (appelés
objets ou instances dans le jargon OO) et manipuler ces variables (ce qu'on
appelle envoyer des messages ou des requêtes ; on envoie un
message et l'objet se débrouille pour le traiter). Les membres (éléments)
d'une même classe partagent des caractéristiques communes : chaque compte dispose
d'un solde, chaque guichetier peut accepter un dépôt, etc... Cependant, chaque
élément a son propre état : chaque compte a un solde différent,
chaque guichetier a un nom. Ainsi, les guichetiers, clients, comptes, transactions, etc... peuvent
tous être représentés par la même entité au sein du programme.
Cette entité est l'objet, et chaque objet appartient à une classe particulière
qui définit ses caractéristiques et ses comportements.
|
 |
 |
 |
So, although what we really do in
object-oriented programming is create new data types, virtually all
object-oriented programming languages use the “class” keyword. When
you see the word “type” think “class” and vice
versa[3].
|
 |
Donc, comme la programmation orientée objet consiste en la
création de nouveaux types de données, quasiment tous les langages orientés
objet utilisent le mot clef « class ». Quand vous voyez le mot
« type » pensez « classe » et inversement "#fn3" name="fnB3">[3].
|
 |
 |
 |
Since a class describes a set of objects
that have identical characteristics (data elements) and behaviors
(functionality), a class is really a
data type because a floating point
number, for example, also has a set of characteristics and behaviors. The
difference is that a programmer defines a class to fit a problem rather than
being forced to use an existing data type that was designed to represent a unit
of storage in a machine. You extend the programming language by adding new data
types specific to your needs. The programming system welcomes the new classes
and gives them all the care and type-checking that it gives to built-in
types.
|
 |
Comme une classe décrit un ensemble d'objets partageant des
caractéristiques communes (données) et des comportements (fonctionnalités),
une classe est réellement un type de données. En effet, un nombre en virgule
flottante par exemple, dispose d'un ensemble de caractéristiques et de comportements. La
différence est qu'un programmeur définit une classe pour représenter un
problème au lieu d'être forcé d'utiliser un type de données conçu
pour représenter une unité de stockage de l'ordinateur. Le langage de programmation
est étendu en ajoutant de nouveaux types de données spécifiques à nos
besoins. Le système de programmation accepte la nouvelle classe et lui donne toute
l'attention et le contrôle de type qu'il fournit aux types
prédéfinis.
|
 |
 |
 |
The object-oriented approach is not
limited to building simulations. Whether or not you agree that any program is a
simulation of the system you’re designing, the use of OOP techniques can
easily reduce a large set of problems to a simple solution.
|
 |
L'approche orientée objet n'est pas limitée aux simulations.
Que vous pensiez ou non que tout programme n'est qu'une simulation du système qu'on
représente, l'utilisation des techniques de la POO peut facilement réduire un
ensemble de problèmes à une solution simple.
|
 |
 |
 |
Once a class is established, you can make
as many objects of that class as you like, and then manipulate those objects as
if they are the elements that exist in the problem you are trying to solve.
Indeed, one of the challenges of object-oriented programming is to create a
one-to-one mapping between the elements in the problem space and objects in the
solution space.
|
 |
Une fois qu'une classe est créée, on peut créer autant
d'objets de cette classe qu'on veut et les manipuler comme s'ils étaient les
éléments du problème qu'on tente de résoudre. En fait, l'une des
difficultés de la programmation orientée objet est de créer une association
un-à-un entre les éléments de l'espace problème et les
éléments de l'espace solution.
|
 |
 |
 |
But how do you get an object to do useful
work for you? There must be a way to make a request of the object so that it
will do something, such as complete a transaction, draw something on the screen,
or turn on a switch. And each object can satisfy only certain requests. The
requests you can make of an object are defined by its interface, and the
type is what determines the interface. A simple example might be a
representation of a light bulb:
|
 |
Mais comment utiliser un objet ? Il faut pouvoir lui demander
d'exécuter une requête, telle que terminer une transaction, dessiner quelque chose
à l'écran, ou allumer un interrupteur. Et chaque objet ne peut traiter que certaines
requêtes. Les requêtes qu'un objet est capable de traiter sont définies par son
interface, et son type est ce qui détermine son interface. Prenons l'exemple d'une
ampoule électrique :
|
 |
 |
 |
|
 |
|
 |
 |
 |
Light lt = new Light(); lt.on();
|
 |
Ampoule amp = new Ampoule(); amp.allumer();
|
 |
 |
 |
The interface establishes what
requests you can make for a particular object. However, there must be code
somewhere to satisfy that request. This, along with the hidden data, comprises
the implementation. From a procedural programming
standpoint, it’s not that complicated. A type has a function associated
with each possible request, and when you make a particular request to an object,
that function is called. This process is usually summarized by saying that you
“send a message” (make a request) to an object, and the object
figures out what to do with that message (it executes code).
|
 |
L'interface précise quelles opérations on peut
effectuer sur un objet particulier. Cependant, il doit exister du code quelque part pour satisfaire
cette requête. Ceci, avec les données cachées,
constitue l'implémentation. Du point de vue de la programmation
procédurale, ce n'est pas si compliqué. Un type dispose d'une fonction
associée à chaque requête possible, et quand on effectue une requête
particulière sur un objet, cette fonction est appelée. Ce mécanisme est
souvent résumé en disant qu'on « envoie un message » (fait une
requête) à un objet, et l'objet se débrouille pour l'interpréter (il
exécute le code associé).
|
 |
 |
 |
Here, the name of the type/class is
Light, the name of this particular Light object is lt,
and the requests that you can make of a Light object are to turn it
on, turn it off, make it brighter, or make it dimmer. You create a Light
object by defining a “reference” (lt) for that object and
calling new to request a new object of that type. To send a message to
the object, you state the name of the object and connect it to the message
request with a period (dot). From the standpoint of the user of a predefined
class, that’s pretty much all there is to programming with
objects.
|
 |
Ici, le nom du type / de la classe est Ampoule, le nom de
l'objet Ampoule créé est amp, et on peut demander
à un objet Ampoule de s'allumer, de s'éteindre, d'intensifier ou de
diminuer sa luminosité. Un objet Ampoule est créé en
définissant une « référence » (amp) pour cet
objet et en appelant new pour créer un nouvel objet de ce type. Pour
envoyer un message à cet objet, il suffit de spécifier le nom de l'objet suivi de la
requête avec un point entre les deux. Du point de vue de l'utilisateur d'une classe
prédéfinie, c'est tout ce qu'il est besoin de savoir pour programmer avec des
objets.
|
 |
 |
 |
The diagram shown above follows the
format of the Unified Modeling
Language (UML). Each class is represented by a box, with the type name in
the top portion of the box, any data members that you care to describe in the
middle portion of the box, and the
member functions (the
functions that belong to this object, which receive any messages you send to
that object) in the bottom portion of the box. Often, only the name of the class
and the public member functions are shown in UML design diagrams, and so the
middle portion is not shown. If you’re interested only in the class name,
then the bottom portion doesn’t need to be shown,
either.
|
 |
L'illustration ci-dessus reprend le formalisme UML (Unified Modeling
Language). Chaque classe est représentée par une boîte, avec le nom du
type dans la partie supérieure, les données membres qu'on décide de
décrire dans la partie du milieu et les fonctions membres (les fonctions
appartenant à cet objet qui reçoivent les messages envoyées à cet
objet) dans la partie du bas de la boîte. Souvent on ne montre dans les diagrammes UML que le
nom de la classe et les fonctions publiques, et la partie du milieu n'existe donc pas. Si seul le
nom de la classe nous intéresse, alors la portion du bas n'a pas besoin d'être
montrée non plus.
|
 |
 |
 |
The hidden implementation
|
 |
L'implémentation cachée
|
 |
 |
 |
It is helpful to break up the playing
field into class creators (those who create new
data types) and client
programmers[4]
(the class consumers who use the data types in their applications). The goal of
the client programmer is to collect a toolbox full of classes to use for rapid
application development. The goal of the class creator is to build a class that
exposes only what’s necessary to the client programmer and keeps
everything else hidden. Why? Because if it’s hidden, the client programmer
can’t use it, which means that the class creator can change the hidden
portion at will without worrying about the impact to anyone else. The hidden
portion usually represents the tender insides of an object that could easily be
corrupted by a careless or uninformed client programmer, so hiding the
implementation reduces program bugs. The concept of
implementation hiding cannot be
overemphasized.
|
 |
Il est plus facile de diviser les personnes en créateurs de
classe (ceux qui créent les nouveaux types de données) et programmeurs
clients [4] (ceux qui utilisent ces
types de données dans leurs applications). Le but des programmeurs clients est de se monter
une boîte à outils pleine de classes réutilisables pour le développement
rapide d'applications (RAD, Rapid Application Development en anglais). Les créateurs de
classes, eux, se focalisent sur la construction d'une classe qui n'expose que le nécessaire
aux programmeurs clients et cache tout le reste. Pourquoi cela ? Parce que si c'est
caché, le programmeur client ne peut l'utiliser, et le créateur de la classe peut
changer la portion cachée comme il l'entend sans se préoccuper de l'impact que cela
pourrait avoir chez les utilisateurs de sa classe. La portion cachée correspond en
général aux données de l'objet qui pourraient facilement être corrompues
par un programmeur client négligent ou mal informé. Ainsi, cacher
l'implémentation réduit considérablement les bugs.
|
 |
 |
 |
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 client programmer, who is
also a programmer, but one who is putting together an application by using your
library, possibly to build a bigger library.
|
 |
Le concept d'implémentation cachée ne saurait être
trop loué : dans chaque relation il est important de fixer des frontières
respectées par toutes les parties concernées. Quand on crée une
bibliothèque, on établit une relation avec un programmeur client, programmeur qui
crée une application (ou une bibliothèque plus conséquente) en utilisant
notre bibliothèque.
|
 |
 |
 |
If all the members of a class are
available to everyone, then the client programmer can do anything with that
class and there’s no way to enforce rules. Even though you might really
prefer that the client programmer not directly manipulate some of the members of
your class, without access control there’s no way to prevent it.
Everything’s naked to the world.
|
 |
Si tous les membres d'une classe sont accessibles pour tout le monde, alors
le programmeur client peut faire ce qu'il veut avec cette classe et il n'y a aucun moyen de faire
respecter certaines règles. Même s'il est vraiment préférable que
l'utilisateur de la classe ne manipule pas directement certains membres de la classe, sans
contrôle d'accès il n'y a aucun moyen de l'empêcher : tout est
exposé à tout le monde.
|
 |
 |
 |
So the first reason for access control is
to keep client programmers’ hands off portions they shouldn’t
touch—parts that are necessary for the internal machinations of the data
type but not part of the interface that users need in order to solve their
particular problems. This is actually a service to users because they can easily
see what’s important to them and what they can ignore.
|
 |
La raison première du contrôle d'accès est donc
d'empêcher les programmeurs clients de toucher à certaines portions auxquelles ils ne
devraient pas avoir accès - les parties qui sont nécessaires pour les manipulations
internes du type de données mais n'appartiennent pas à l'interface dont les
utilisateurs ont besoin pour résoudre leur problème. C'est en réalité
un service rendu aux utilisateurs car ils peuvent voir facilement ce qui est important pour leurs
besoins et ce qu'ils peuvent ignorer.
|
 |
 |
 |
The second 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. For example,
you might implement a particular class in a simple fashion to ease development,
and then later discover that you need to rewrite it in order to make it run
faster. If the interface and implementation are clearly separated and protected,
you can accomplish this
easily.
|
 |
La deuxième raison d'être du contrôle d'accès est
de permettre au concepteur de la bibliothèque de changer le fonctionnement interne de la
classe sans se soucier des effets que cela peut avoir sur les programmeurs clients. Par exemple, on
peut implémenter une classe particulière d'une manière simpliste afin
d'accélérer le développement, et se rendre compte plus tard qu'on a besoin de
la réécrire afin de gagner en performances. Si l'interface et l'implémentation
sont clairement séparées et protégées, cela peut être
réalisé facilement.
|
 |
 |
 |
Java uses three explicit keywords to set
the boundaries in a class: public, private, and protected.
Their use and meaning are quite straightforward. These access specifiers
determine who
can use the definitions that follow. public means
the following definitions are available to everyone. The private
keyword, on the other hand, means that no one can access
those definitions except you, the creator of the type, inside member functions
of that type. private is a brick wall between you and the client
programmer. If someone tries to access a private member, they’ll
get a compile-time error. protected acts like
private, with the exception that an inheriting class has access to
protected members, but not private members. Inheritance will be
introduced shortly.
|
 |
Java utilise trois mots clefs pour fixer des limites au sein d'une
classe : public, private et protected. Leur
signification et leur utilisation est relativement explicite. Ces spécificateurs
d'accès déterminent qui peut utiliser les définitions qui
suivent. public veut dire que les définitions suivantes sont
disponibles pour tout le monde. Le mot clef private, au contraire, veut dire
que personne, le créateur de la classe et les fonctions internes de ce type mis à
part, ne peut accéder à ces définitions. private est un mur
de briques entre le créateur de la classe et le programmeur client. Si quelqu'un tente
d'accéder à un membre défini comme private, ils
récupèreront une erreur lors de la compilation. protected se
comporte comme private, en moins restrictif : une classe
dérivée a accès aux membres protected, mais pas aux membres
private. L'héritage sera introduit bientôt.
|
 |
 |
 |
Java also has a “default”
access, which comes into play if you don’t use one of the aforementioned
specifiers. This is sometimes called “friendly” access because
classes can access the friendly members of other classes in the same package,
but outside of the package those same friendly members appear to be
private.
|
 |
Java dispose enfin d'un accès « par
défaut », utilisé si aucun de ces spécificateurs n'est
mentionné. Cet accès est souvent appelé accès
« amical » car les classes peuvent accéder aux membres amicaux des
autres classes du même package, mais en dehors du package ces mêmes membres amicaux se
comportent comme des attributs private.
|
 |
 |
 |
Reusing the implementation
|
 |
Réutilisation de l'implémentation
|
 |
 |
 |
Once a class has been created and tested,
it should (ideally) represent a useful unit of code. It turns out that this
reusability is not nearly so easy to achieve as many would
hope; it takes experience and insight to produce a good design. But once you
have such a design, it begs to be reused. Code reuse is one of the greatest
advantages that object-oriented programming languages provide.
|
 |
Une fois qu'une classe a été créée et
testée, elle devrait (idéalement) représenter une partie de code utile. Il
s'avère que cette réutilisabilité n'est pas aussi facile à obtenir
que cela ; cela demande de l'expérience et de l'anticipation pour produire une bonne
conception. Mais une fois bien conçue, cette classe ne demande qu'à être
réutilisée. La réutilisation de code est l'un des plus grands avantages que
les langages orientés objets fournissent.
|
 |
 |
 |
The simplest way to reuse a class is to
just use an object of that class directly, but you can also place an object of
that class inside a new class. We call this “creating a
member object.” Your new class
can be made up of any number and type of other objects, in any combination that
you need to achieve the functionality desired in your new class. Because you are
composing a new class from existing classes, this concept is called
composition (or more generally,
aggregation). Composition is often referred to as a
“has-a” relationship, as in “a car has
an engine.”
|
 |
La manière la plus simple de réutiliser une classe est
d'utiliser directement un objet de cette classe, mais on peut aussi placer un objet de cette classe
à l'intérieur d'une nouvelle classe. On appelle cela « "Index72">créer un objet membre ». La nouvelle classe peut être
constituée de n'importe quel nombre d'objets d'autres types, selon la combinaison
nécessaire pour que la nouvelle classe puisse réaliser ce pour quoi elle a
été conçue. Parce que la nouvelle classe est composée à partir
de classes existantes, ce concept est appelé composition (ou, plus
généralement, agrégation). On se réfère souvent
à la composition comme à une relation « possède-un »,
comme dans « une voiture possède un moteur ».
|
 |
 |
 |
|
 |
|
 |
 |
 |
(The above UML
diagram indicates composition with the filled diamond, which states there is one
car. I will typically use a simpler form: just a line, without the diamond, to
indicate an
association.[5])
|
 |
(Le diagramme UML ci-dessus indique la composition avec le losange
rempli, qui indique qu'il y a un moteur dans une voiture. J'utiliserai une forme plus simple :
juste une ligne, sans le losange, pour indiquer une association "fnB5">[5].)
|
 |
 |
 |
Composition comes with a great deal of
flexibility. The member objects of your new class are usually private, making
them inaccessible to the client programmers who are using the class. This allows
you to change those members without disturbing existing client code. You can
also change the member objects at run-time, to dynamically change the behavior
of your program. Inheritance, which is described next, does not have this
flexibility since the compiler must place compile-time restrictions on classes
created with inheritance.
|
 |
La composition s'accompagne d'une grande flexibilité : les
objets membres de la nouvelle classe sont généralement privés, ce qui les rend
inaccessibles aux programmeurs clients de la classe. Cela permet de modifier ces membres sans
perturber le code des clients existants. On peut aussi changer les objets membres lors la phase
d'exécution, pour changer dynamiquement le comportement du programme. L'héritage,
décrit juste après, ne dispose pas de cette flexibilité car le compilateur
doit placer des restrictions lors de la compilation sur les classes créées avec
héritage.
|
 |
 |
 |
Because inheritance is so important in
object-oriented programming it is often highly emphasized, and the new
programmer can get the idea that inheritance should be used everywhere. This can
result in awkward and overly complicated designs. Instead, you should first look
to composition when creating new classes, since it is simpler and more flexible.
If you take this approach, your designs will be cleaner. Once you’ve had
some experience, it will be reasonably obvious when you need
inheritance.
|
 |
Parce que la notion d'héritage est très importante au sein de
la programmation orientée objet, elle est trop souvent martelée, et le nouveau
programmeur pourrait croire que l'héritage doit être utilisé partout. Cela
mène à des conceptions ultra compliquées et cauchemardesques. La composition
est la première approche à examiner lorsqu'on crée une nouvelle classe, car
elle est plus simple et plus flexible. Le design de la classe en sera plus propre. Avec de
l'expérience, les endroits où utiliser l'héritage deviendront raisonnablement
évidents.
|
 |
 |
 |
Inheritance:reusing the interface
|
 |
Héritage : réutilisation de l'interface
|
 |
 |
 |
By itself, the idea of an object is a
convenient tool. It allows you to package data and functionality together by
concept, so you can represent an appropriate problem-space idea rather
than being forced to use the idioms of the underlying machine. These concepts
are expressed as fundamental units in the programming language by using the
class
keyword.
|
 |
L'idée d'objet en elle-même est un outil efficace. Elle permet
de fournir des données et des fonctionnalités liées entre elles par concept,
afin de représenter une idée de l'espace problème plutôt que
d'être forcé d'utiliser les idiomes internes de la machine. Ces concepts sont
exprimés en tant qu'unité fondamentale dans le langage de programmation en utilisant
le mot clef class.
|
 |
 |
 |
It seems a pity, however, to go to all
the trouble to create a class and then be forced to create a brand new one that
might have similar functionality. It’s nicer if we can take the existing
class, clone it, and then make additions and modifications to the clone. This is
effectively what you get with inheritance, with the
exception that if the original class (called the base or super or
parent class) is changed, the modified “clone” (called the
derived or inherited or sub or child class)
also reflects those changes.
|
 |
Il serait toutefois dommage, après s'être donné
beaucoup de mal pour créer une classe de devoir en créer une toute nouvelle qui
aurait des fonctionnalités similaires. Ce serait mieux si on pouvait prendre la classe
existante, la cloner, et faire des ajouts ou des modifications à ce clone. C'est ce
que l'héritage permet de faire, avec la restriction suivante : si la
classe originale (aussi appelée classe de base, superclasse ou classe
parent) est changée, le « clone » modifié
(appelé classe dérivée, héritée,
enfant ou sousclasse) répercutera aussi ces changements.
|
 |
 |
 |
|
 |
|
 |
 |
 |
(The arrow in the above UML diagram
points from the derived class to the base class. As you will see, there can be
more than one derived class.)
|
 |
(La flèche dans le diagramme UML ci-dessus pointe de la classe
dérivée vers la classe de base. Comme vous le verrez, il peut y avoir plus d'une
classe dérivée.)
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |