Vous êtes sur la page 1sur 706

Cet ouvrage a bnci des relectures attentives des zCorrecteurs.

Sauf mention contraire, le contenu de cet ouvrage est publi sous la licence : Creative Commons BY-NC-SA 2.0 La copie de cet ouvrage est autorise sous rserve du respect des conditions de la licence Texte complet de la licence disponible sur : http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Simple IT 2011 - ISBN : 978-2-9535278-3-4

Avant-propos

i vous lisez ces lignes, c'est que nous avons au moins deux choses en commun : l'informatique vous intresse et vous avez envie d'apprendre programmer. Enn, quand je dis en commun, je voulais dire en commun avec moi au moment o je voulais apprendre la programmation. Pour moi, tout a commenc sur un site maintenant trs connu : le Site du Zro. tant dbutant et cherchant tout prix des cours adapts mon niveau, je suis naturellement tomb amoureux de ce site qui propose des cours d'informatique accessibles au plus grand nombre. Vous l'aurez sans doute remarqu, trouver un cours d'informatique simple et clair (sur les rseaux, les machines, la programmation. . .) est habituellement un vrai parcours du combattant. Je ne me suis pas dcourag et je me suis professionnalis, via une formation diplmante, tout en suivant l'actualit de mon site prfr. . . Au sein de cette formation, j'ai pu voir divers aspects de mon futur mtier, notamment la programmation dans les langages PHP, C#, JavaScript et, bien sr, Java. Trs vite, j'ai aim travailler avec ce dernier, d'une part parce qu'il est agrable manipuler, souple utiliser en demandant toutefois de la rigueur (ce qui oblige structurer ses programmes), et d'autre part parce qu'il existe de nombreuses ressources disponibles sur Internet (mais pas toujours trs claires pour un dbutant). J'ai depuis obtenu mon diplme et trouv un emploi, mais je n'ai jamais oubli la dicult des premiers temps. Comme le Site du Zro permet d'crire des tutoriels et de les partager avec la communaut, j'ai dcid d'employer les connaissances acquises durant ma formation et dans mon travail rdiger un tutoriel permettant d'aborder mon langage de prdilection avec simplicit. J'ai donc pris mon courage deux mains et j'ai commenc crire. Beaucoup de lecteurs se sont rapidement montrs intresss, pour mon plus grand plaisir. De ce fait, mon tutoriel a t mis en avant sur le site et, aujourd'hui, il est adapt dans la collection  Livre du Zro . Je suis heureux du chemin parcouru, heureux d'avoir pu aider tant de dbutants et heureux de pouvoir vous aider votre tour !

CHAPITRE 0. AVANT-PROPOS

Et Java dans tout a ?


Java est un langage de programmation trs utilis, notamment par un grand nombre de dveloppeurs professionnels, ce qui en fait un langage incontournable actuellement. Voici les caractristiques de Java en quelques mots.  Java est un langage de programmation moderne dvelopp par Sun Microsystems, aujourd'hui rachet par Oracle. Il ne faut surtout pas le confondre avec JavaScript (langage de script utilis sur les sites Web), car ils n'ont rien voir.  Une de ses plus grandes forces est son excellente portabilit : une fois votre programme cr, il fonctionnera automatiquement sous Windows, Mac, Linux, etc.  On peut faire de nombreux types de programmes avec Java :  des applications, sous forme de fentre ou de console ;  des applets, qui sont des programmes Java incorpors des pages Web ;  des applications pour appareils mobiles, comme les smartphones, avec J2ME (Java 2 Micro Edition) ;  des sites web dynamiques, avec J2EE (Java 2 Enterprise Edition, maintenant JEE) ;  et bien d'autres : JMF (Java Media Framework), J3D pour la 3D. . . Comme vous le voyez, Java permet de raliser une trs grande quantit d'applications direntes ! Mais. . . comment apprendre un langage si vaste qui ore tant de possibilits ? Heureusement, ce livre est l pour tout vous apprendre sur Java partir de zro. Java est donc un langage de programmation, un langage dit compil : il faut comprendre par l que ce que vous allez crire n'est pas directement comprhensible et utilisable par votre ordinateur. Nous devrons donc passer par une tape de compilation (tape obscure o votre code source est entirement transform). En fait, on peut distinguer trois grandes phases dans la vie d'un code Java :  la phase d'criture du code source, en langage Java ;  la phase de compilation de votre code ;  la phase d'excution. Ces phases sont les mmes pour la plupart des langages compils (C, C++. . .). Par contre, ce qui fait la particularit de Java, c'est que le rsultat de la compilation n'est pas directement utilisable par votre ordinateur. Les langages mentionns ci-dessus permettent de faire des programmes directement comprhensibles par votre machine aprs compilation, mais avec Java, c'est lgrement dirent. En C++ par exemple, si vous voulez faire en sorte que votre programme soit exploitable sur une machine utilisant Windows et sur une machine utilisant Linux, vous allez devoir prendre en compte les spcicits de ces deux systmes d'exploitation dans votre code source et compiler une version spciale pour chacun d'eux. Avec Java, c'est un programme appel la machine virtuelle qui va se charger de retranscrire le rsultat de la compilation en langage machine, interprtable par celle-ci. Vous n'avez pas vous proccuper des spcicits de la machine qui va excuter votre programme : la machine virtuelle Java s'en charge pour vous ! ii

QU'ALLEZ-VOUS APPRENDRE EN LISANT CE LIVRE ?

Qu'allez-vous apprendre en lisant ce livre ?


Ce livre a t conu en partant du principe que vous ne connaissez rien la programmation. Voil le plan en quatre parties que nous allons suivre tout au long de cet ouvrage. 1. Les bases de Java : nous verrons ici ce qu'est Java et comment il fonctionne. Nous crerons notre premier programme, en utilisant des variables, des oprateurs, des conditions, des boucles. . . Nous apprendrons les bases du langage, qui vous seront ncessaires par la suite. 2. Java et la Programmation Oriente Objet : aprs avoir dompt les bases du langage, vous allez devoir apprivoiser une notion capitale : l'objet. Vous apprendrez encapsuler vos morceaux de code an de les rendre modulables et rutilisables, mais il y aura du travail fournir. 3. Les interfaces graphiques : l, nous verrons comment crer des interfaces graphiques et comment les rendre interactives. C'est vrai que jusqu' prsent, nous avons travaill en mode console. Il faudra vous accrocher un peu car il y a beaucoup de composants utilisables, mais le jeu en vaut la chandelle ! Nous passerons en revue dirents composants graphiques tels que les champs de texte, les cases cocher, les tableaux, les arbres ainsi que quelques notions spciques comme le drag'n drop. 4. Interactions avec les bases de donnes : de nos jours, avec la course aux donnes, beaucoup de programmes doivent interagir avec ce qu'on appelle des bases de donnes. Dans cette partie, nous verrons comment s'y connecter, comment rcuprer des informations et comment les exploiter.

Comment lire ce livre ?


Suivez l'ordre des chapitres
Lisez ce livre comme on lit un roman. Il a t conu de cette faon. Contrairement beaucoup de livres techniques o il est courant de lire en diagonale et de sauter certains chapitres, ici il est trs fortement recommand de suivre l'ordre du cours, moins que vous ne soyez dj un peu expriments.

Pratiquez en mme temps


Pratiquez rgulirement. N'attendez pas d'avoir ni la lecture de ce livre pour allumer votre ordinateur et faire vos propres essais. iii

CHAPITRE 0. AVANT-PROPOS

Utilisez les codes web !


An de tirer parti du Site du Zro dont est issu ce livre, celui-ci vous propose ce qu'on appelle des  codes web . Ce sont des codes six chires entrer sur une page du Site du Zro pour tre automatiquement redirig vers un site web sans avoir en recopier l'adresse. Pour utiliser les codes web, rendez-vous sur la page suivante 1 :
http://www.siteduzero.com/codeweb.html

Un formulaire vous invite rentrer votre code web. Faites un premier essai avec le code ci-dessous :  Tester le code web Code web : 123456  Ces codes web ont deux intrts :  vous faire tlcharger les codes source inclus dans ce livre, ce qui vous vitera d'avoir recopier certains codes un peu longs ;  vous rediriger vers les sites web prsents tout au long du cours. Ce systme de redirection nous permet de tenir jour le livre que vous avez entre les mains sans que vous ayez besoin d'acheter systmatiquement chaque nouvelle dition. Si un site web change d'adresse, nous modierons la redirection mais le code web utiliser restera le mme. Si un site web disparat, nous vous redirigerons vers une page du Site du Zro expliquant ce qui s'est pass et vous proposant une alternative. En clair, c'est un moyen de nous assurer de la prennit de cet ouvrage sans que vous ayez faire quoi que ce soit !

Ce livre est issu du Site du Zro


Cet ouvrage reprend le cours Java prsent sur le Site du Zro dans une dition revue et corrige, avec de nombreuses mises jour. Il reprend les lments qui ont fait le succs des cours du site, c'est--dire leur approche progressive et pdagogique, le ton dcontract et lger, ainsi que les TP vous permettant de rellement pratiquer de faon autonome. Ce livre s'adresse donc toute personne dsireuse d'apprendre les bases de la programmation en Java, que ce soit :  par curiosit ;  par intrt personnel ;  par besoin professionnel.
1. Vous pouvez aussi utiliser le formulaire de recherche du Site du Zro, section  Code Web .

iv

REMERCIEMENTS

Remerciements
Comme pour la plupart des ouvrages, beaucoup de personnes ont particip de prs ou de loin l'laboration de ce livre et j'en prote donc pour les en remercier.  Ma compagne, Manuela, qui me supporte et qui tolre mes heures passes crire les tutoriels pour le Site du Zro. Un merci spcial toi qui me prends dans tes bras lorsque a ne va pas, qui m'embrasses lorsque je suis triste, qui me souris lorsque je te regarde, qui me donnes tant d'amour lorsque le temps est maussade : pour tout a et plus encore, je t'aime ;  Agns HAASSER (Ttie), Damien SMEETS (Karl Yeurl), Mickal SALAMIN (micky), Franois GLORIEUX (Nox), Christophe TAFANI-DEREEPER, Romain CAMPILLO (Le Chapelier Toqu), Charles DUPR (Barbatos), Maxence CORDIEZ (Ziame), Philippe LUTUN (ptipilou), zCorrecteurs m'ayant accompagn dans la correction de cet ouvrage ;  Mathieu NEBRA (alias M@teo21), pre fondateur du Site du Zro, qui m'a fait conance, soutenu dans mes dmarches et qui m'a donn de prcieux conseils ;  Tous les Zros qui m'ont apport leur soutien et leurs remarques ;  Toutes les personnes qui m'ont contact pour me faire des suggestions et m'apporter leur expertise. Merci aussi toutes celles et ceux qui m'ont apport leur soutien et qui me permettent d'apprendre toujours plus au quotidien, mes collgues de travail :  Thomas, qui a toujours des questions sur des sujets totalement dlirants ;  Angelo, mon chef ador, qui est un puits de science en informatique ;  Olivier, la force zen, qui n'a pas son pareil pour aller droit au but ;  Dylan, discret mais d'une comptence plus que certaine dans des domaines aussi divers que varis ;  Jrme, que j'ai martyris mais qui, j'en suis persuad, a ador. . . :-)

CHAPITRE 0. AVANT-PROPOS

vi

Sommaire

Avant-propos
Et Java dans tout a ? . . . . . . . . . . . . Qu'allez-vous apprendre en lisant ce livre ? Comment lire ce livre ? . . . . . . . . . . . . Ce livre est issu du Site du Zro . . . . . . Remerciements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

i
ii iii iii iv v

I Les bases de Java


1 Installer les outils de dveloppement

1
3

Installer les outils ncessaires . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Votre premier programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2 Les variables et les oprateurs

23

Les dirents types de variables . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Les oprateurs arithmtiques . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Les conversions, ou  cast  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3 Lire les entres clavier

33

La classe Scanner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Rcuprer ce que vous tapez . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4 Les conditions
vii

39

SOMMAIRE La structure if... else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 La structure switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 La condition ternaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5 Les boucles

47

La boucle while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 La boucle do... while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 La boucle for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6 TP : conversion Celsius - Fahrenheit

55

laboration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Correction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

7 Les tableaux

61

Tableau une dimension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Les tableaux multidimensionnels . . . . . . . . . . . . . . . . . . . . . . . . . 62 Utiliser et rechercher dans un tableau . . . . . . . . . . . . . . . . . . . . . . 63

8 Les mthodes de classe

69

Quelques mthodes utiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Crer sa propre mthode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 La surcharge de mthode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

II Java et la Programmation Oriente Objet


9 Votre premire classe

79
81

Structure de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Les constructeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Accesseurs et mutateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Les variables de classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 Le principe d'encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

10 L'hritage

99

Le principe de l'hritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Le polymorphisme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 viii

SOMMAIRE

11 Modliser ses objets grce UML

111

Prsentation d'UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Modliser ses objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Modliser les liens entre les objets . . . . . . . . . . . . . . . . . . . . . . . . 114

12 Les packages

119

Cration d'un package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Droits d'accs entre les packages . . . . . . . . . . . . . . . . . . . . . . . . . 121

13 Les classes abstraites et les interfaces

123

Les classes abstraites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Les interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Le pattern strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

14 Les exceptions

157

Le bloc try{...} catch{...} . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Les exceptions personnalises . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 La gestion de plusieurs exceptions . . . . . . . . . . . . . . . . . . . . . . . . 164

15 Les ux d'entre/sortie

167

Utilisation de java.io . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Utilisation de java.nio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Le pattern decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

16 Les numrations

197

Avant les numrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Une solution : les enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

17 Les collections d'objets


Les dirents types de collections Les objets List . . . . . . . . . . Les objets Map . . . . . . . . . . Les objets Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

203
204 205 208 209

18 La gnricit en Java

213

Principe de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Gnricit et collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 ix

SOMMAIRE

19 Java et la rexivit

227

L'objet Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 Instanciation dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232

III Les interfaces graphiques


20 Notre premire fentre

237
239

L'objet JFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 L'objet JPanel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Les objets Graphics et Graphics2D . . . . . . . . . . . . . . . . . . . . . . . 246

21 Le l rouge : une animation

259

Cration de l'animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Amliorations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

22 Positionner des boutons

269

Utiliser la classe JButton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 Positionner son composant : les layout managers . . . . . . . . . . . . . . . . 272

23 Interagir avec des boutons


Une classe Bouton personnalise . . . . . . . . . . . . . . Interagir avec son bouton . . . . . . . . . . . . . . . . . . tre l'coute de ses objets : le design pattern Observer Cadeau : un bouton personnalis optimis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

289
290 298 318 327

24 TP : une calculatrice
laboration . . . . . . . . . Conception . . . . . . . . . Correction . . . . . . . . . . Gnrer un .jar excutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

331
332 332 333 338

25 Excuter des tches simultanment


Une classe hrite de Thread Utiliser l'interface Runnable . Synchroniser ses threads . . . Contrler son animation . . . x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

345
346 350 354 355

SOMMAIRE

26 Les champs de formulaire


Les listes : l'objet JComboBox . . . . . . . . . Les cases cocher : l'objet JCheckBox . . . . Les champs de texte : l'objet JTextField . . Contrle du clavier : l'interface KeyListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

359
360 370 381 385

27 Les menus et botes de dialogue

391

Les botes de dialogue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 Les menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408

28 TP : l'ardoise magique
Cahier des charges . . . Prrequis . . . . . . . . Correction . . . . . . . . Amliorations possibles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

439
440 441 442 448

29 Conteneurs, sliders et barres de progression

449

Autres conteneurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 Enjoliver vos IHM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467

30 Les arbres et leur structure


La composition des arbres . . . . Des arbres qui vous parlent . . . Dcorez vos arbres . . . . . . . . Modier le contenu de nos arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

471
472 476 481 486

31 Les interfaces de tableaux


Premiers pas . . . . . . . . . . . Gestion de l'achage . . . . . . . Interaction avec l'objet JTable . Ajouter des lignes et des colonnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

495
496 497 508 515

32 TP : le pendu

519

Cahier des charges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 Prrequis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 Correction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 xi

SOMMAIRE

33 Mieux structurer son code : le pattern MVC


Premiers pas Le modle . . Le contrleur La vue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

525
526 528 531 534

34 Le Drag'n Drop
Prsentation . . . . . . . . . . . . . . Fonctionnement . . . . . . . . . . . Crer son propre TransferHandler . Activer le drop sur un JTree . . . . Eet de dplacement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

539
540 543 547 553 558

35 Mieux grer les interactions avec les composants

565

Prsentation des protagonistes . . . . . . . . . . . . . . . . . . . . . . . . . . 566 Utiliser l'EDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 La classe SwingWorker<T, V> . . . . . . . . . . . . . . . . . . . . . . . . . . . 570

IV Interactions avec les bases de donnes


36 JDBC : la porte d'accs aux bases de donnes

577
579

Rappels sur les bases de donnes . . . . . . . . . . . . . . . . . . . . . . . . . 580 Prparer la base de donnes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584 Se connecter la base de donnes . . . . . . . . . . . . . . . . . . . . . . . . . 591

37 Fouiller dans sa base de donnes


Le couple Statement  ResultSet . Les requtes prpares . . . . . . . . Modier des donnes . . . . . . . . . Statement, toujours plus fort . . . . Grer les transactions manuellement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

597
598 607 613 615 617

38 Limiter le nombre de connexions

621

Pourquoi ne se connecter qu'une seule fois ? . . . . . . . . . . . . . . . . . . . 622 Le pattern singleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622 xii

SOMMAIRE Le singleton dans tous ses tats . . . . . . . . . . . . . . . . . . . . . . . . . . 625

39 TP : un testeur de requtes

629

Cahier des charges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 Quelques captures d'cran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 Correction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630

40 Lier ses tables avec des objets Java : le pattern DAO

633

Avant toute chose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634 Le pattern DAO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 Le pattern factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649

xiii

SOMMAIRE

xiv

Premire partie
Les bases de Java

Chapitre

1
Dicult :

Installer les outils de dveloppement

'un des principes phares de Java rside dans sa machine virtuelle : celle-ci assure tous les dveloppeurs Java qu'un programme sera utilisable avec tous les systmes d'exploitation sur lesquels est installe une machine virtuelle Java. Lors de la phase de compilation de notre code source, celui-ci prend une forme intermdiaire appele byte code : c'est le fameux code inintelligible pour votre machine, mais interprtable par la machine virtuelle Java. Cette dernire porte un nom : on parle plus communment de JRE (Java Runtime Environment). Plus besoin de se soucier des spcicits lies tel ou tel OS (Operating System, soit systme d'exploitation). Nous pourrons donc nous consacrer entirement notre programme. An de nous simplier la vie, nous allons utiliser un outil de dveloppement, ou IDE (Integrated Development Environment), pour nous aider crire nos futurs codes source. . . Nous allons donc avoir besoin de direntes choses an de pouvoir crer des programmes Java : la premire est ce fameux JRE !

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT

Installer les outils ncessaires


JRE ou JDK
Tlchargez votre environnement Java sur le site d'Oracle.


Tlcharger JRE Code web : 924260 

Choisissez la dernire version stable (gure 1.1).

Figure

1.1  Encart de tlchargement

Vous avez sans doute remarqu qu'on vous propose de tlcharger soit le JRE, soit le JDK 1 . La dirence entre ces deux environnements est crite, mais pour les personnes fches avec l'anglais, sachez que le JRE contient tout le ncessaire pour faire en sorte que vos programmes Java puissent tre excuts sur votre ordinateur ; le JDK, en plus de contenir le JRE, contient tout le ncessaire pour dvelopper, compiler. . . L'IDE contenant dj tout le ncessaire pour le dveloppement et la compilation, nous n'avons besoin que du JRE. Une fois que vous avez cliqu sur  Download JRE , vous arrivez sur la page correspondante (gure 1.2). Slectionnez votre systme d'exploitation et cochez la case :  I agree to the Java SE Development Kit 6 License Agreement . Lorsque vous serez l'cran correspondant (gure 1.3), slectionnez celui de votre choix puis validez. Je vous ai dit que Java permet de dvelopper dirents types d'applications : il y a donc des environnements permettant de crer des programmes pour direntes platesformes.  J2SE 2 : permet de dvelopper des applications dites  client lourd , par exemple
1. Java Development Kit. 2. Java 2 Standard Edition, celui qui nous intresse dans cet ouvrage.

INSTALLER LES OUTILS NCESSAIRES

Figure

1.2  Page de choix de votre systme d'exploitation

Figure

1.3  Choix de l'excutable

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT Word, Excel, la suite OpenOce.org. . . Toutes ces applications sont des  clients lourds . C'est ce que nous allons faire dans ce livre.  J2EE 3 : permet de dvelopper des applications web en Java. On parle aussi de clients lgers.  J2ME 4 : permet de dvelopper des applications pour appareils portables, comme des tlphones portables, des PDA. . .

Eclipse IDE
Avant toute chose, quelques mots sur le projet Eclipse. Eclipse IDE est un environnement de dveloppement libre permettant de crer des programmes dans de nombreux langages de programmation (Java, C++, PHP. . .). C'est en somme l'outil que nous allons utiliser pour programmer.

Eclipse IDE est lui-mme principalement crit en Java.


Je vous invite donc tlcharger Eclipse IDE. Tlcharger Eclipse Code web : 395144  Accdez la page de tlchargement puis choisissez  Eclipse IDE for Java Developers , en choisissant la version d'Eclipse correspondant votre OS 5 (gure 1.4).


Figure

1.4  Version d'Eclipse IDE

Slectionnez maintenant le miroir que vous souhaitez utiliser pour obtenir Eclipse. Voil, vous n'avez plus qu' attendre la n du tlchargement. Pour ceux qui l'avaient devin, Eclipse est le petit logiciel qui va nous permettre de dvelopper nos applications ou nos applets, et aussi celui qui va compiler tout a. Notre logiciel va donc permettre de traduire nos futurs programmes Java en langage byte code, comprhensible uniquement par votre JRE, frachement install. La spcicit d'Eclipse IDE vient du fait que son architecture est totalement dveloppe autour de la notion de plug-in. Cela signie que toutes ses fonctionnalits sont dveloppes en tant que plug-ins. Pour faire court, si vous voulez ajouter des fonctionnalits Eclipse, vous devez :
3. Java 2 Enterprise Edition. 4. Java 2 Micro Edition. 5. Operating System = systme d'exploitation.

INSTALLER LES OUTILS NCESSAIRES  tlcharger le plug-in correspondant ;  copier les chiers spcis dans les rpertoires spcis ;  dmarrer Eclipse, et a y est !

Lorsque vous tlchargez un nouveau plug-in pour Eclipse, celui-ci se prsente souvent comme un dossier contenant gnralement deux sous-dossiers : un dossier  plugins  et un dossier  features . Ces dossiers existent aussi dans le rpertoire d'Eclipse. Il vous faut donc copier le contenu des dossiers de votre plug-in vers le dossier correspondant dans Eclipse (plugins dans plugins, et features dans features).
Vous devez maintenant avoir une archive contenant Eclipse. Dcompressez-la o vous voulez, puis entrez dans ce dossier (gure 1.5). Cela fait, lancez Eclipse.

Figure

1.5  Contenu du dossier Eclipse

Ici (gure 1.6), Eclipse vous demande dans quel dossier vous souhaitez enregistrer vos projets ; sachez que rien ne vous empche de spcier un autre dossier que celui propos par dfaut.

Figure

1.6  Premire fentre Eclipse 7

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT Une fois cette tape eectue, vous arrivez sur la page d'accueil d'Eclipse. Si vous avez envie d'y jeter un il, allez-y.

Prsentation rapide de l'interface


Je vais maintenant vous faire faire un tour rapide de l'interface d'Eclipse.

Le menu  File  (gure 1.7)

Figure

1.7  Menu  File 

C'est ici que nous pourrons crer de nouveaux projets Java, les enregistrer et les exporter le cas chant. Les raccourcis retenir sont :  ALT + SHIFT + N : nouveau projet ;  CTRL + S : enregistrer le chier o l'on est positionn ;  CTRL + SHIFT + S : tout sauvegarder ;  CTRL + W : fermer le chier o l'on est positionn ;  CTRL + SHIFT + W : fermer tous les chiers ouverts. 8

INSTALLER LES OUTILS NCESSAIRES

Figure

1.8  Menu  Edit 

Le menu  Edit  (gure 1.8)


Dans ce menu, nous pourrons utiliser les commandes  copier ,  coller , etc. Ici, les raccourcis retenir sont :  CTRL + C : copier la slection ;  CTRL + X : couper la slection ;  CTRL + V : coller la slection ;  CTRL + A : tout slectionner ;  CTRL + F : chercher-remplacer.

Le menu  Window  (gure 1.9)

Figure

1.9  Menu  Window  9

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT Dans celui-ci, nous pourrons congurer Eclipse selon nos besoins.

La barre d'outils (gure 1.10)

Figure

1.10  Barre d'outils

Nous avons dans l'ordre : 1. 2. 3. 4. 5. 6. nouveau gnral. Cliquer sur ce bouton revient faire  Fichier / Nouveau  ; enregistrer. Revient faire CTRL + S ; imprimer ; excuter la classe ou le projet spci. Nous verrons ceci plus en dtail ; crer un nouveau projet. Revient faire  Fichier / Nouveau / Java Project  ; crer une nouvelle classe, c'est--dire en fait un nouveau chier. Revient faire  Fichier / Nouveau / Classe .

Maintenant, je vais vous demander de crer un nouveau projet Java (gures 1.11 et 1.12).

Figure

1.11  Cration de projet Java - tape 1

Renseignez le nom de votre projet comme je l'ai fait (encadr 1). Vous pouvez aussi voir o sera enregistr ce projet (encadr 2). Un peu plus compliqu, maintenant : vous avez donc un environnement Java sur votre machine, mais dans le cas o vous en auriez plusieurs, vous pouvez aussi spcier Eclipse quel JRE 6 utiliser pour ce projet. Vous devriez avoir un nouveau projet dans la fentre de gauche (gure 1.13).
6. Vous pourrez changer ceci tout moment dans Eclipse en allant dans  Window / Preferences , en dpliant l'arbre  Java  dans la fentre et en choisissant  Installed JRE .

10

INSTALLER LES OUTILS NCESSAIRES

Figure

1.12  Cration de projet Java - tape 2

Figure

1.13  Explorateur de projet 11

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT Pour boucler la boucle, ajoutons ds maintenant une nouvelle classe dans ce projet comme nous avons appris le faire plus tt. Voici la fentre sur laquelle vous devriez tomber : gure 1.14.

Une classe est un ensemble de codes contenant plusieurs instructions que doit eectuer votre programme. Ne vous attardez pas trop sur ce terme, nous aurons l'occasion d'y revenir.

Figure

1.14  Cration d'une classe

Dans l'encadr 1, nous pouvons voir o seront enregistrs nos chiers Java. Dans l'encadr 2, nommez votre classe Java ; moi, j'ai choisi sdz1. Dans l'encadr 3, Eclipse vous demande si cette classe a quelque chose de particulier. Eh bien oui ! Cochez  public static void main(String[] args) 7 , puis cliquez sur  Finish . Avant de commencer coder, nous allons explorer l'espace de travail (gure 1.15). Dans l'encadr de gauche, vous trouverez le dossier de votre projet ainsi que son contenu. Ici, vous pourrez grer votre projet comme bon vous semble (ajout, suppression. . .). Dans l'encadr positionn au centre, je pense que vous avez devin : c'est ici que nous
7. Nous reviendrons plus tard sur ce point.

12

INSTALLER LES OUTILS NCESSAIRES

Figure

1.15  Fentre principale

13

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT allons crire nos codes source. Dans l'encadr du bas, c'est l que vous verrez apparatre le contenu de vos programmes. . . ainsi que les erreurs ventuelles ! Et pour nir, c'est dans l'encadr de droite, ds que nous aurons appris coder nos propres fonctions et nos objets, que la liste des mthodes et des variables sera ache.

Votre premier programme


Comme je vous l'ai maintes fois rpt, les programmes Java sont, avant d'tre utiliss par la machine virtuelle, prcompils en byte code (par votre IDE ou la main). Ce byte code n'est comprhensible que par une JVM, et c'est celle-ci qui va faire le lien entre ce code et votre machine. Vous aviez srement remarqu que sur la page de tlchargement du JRE, plusieurs liens taient disponibles :  un lien pour Windows ;  un lien pour Mac ;  un lien pour Linux. Ceci, car la machine virtuelle Java se prsente diremment selon qu'on se trouve sous Mac, sous Linux ou encore sous Windows. Par contre, le byte code, lui, reste le mme quel que soit l'environnement avec lequel a t dvelopp et prcompil votre programme Java.

Consquence directe : quel que soit l'OS sous lequel a t cod un programme Java, n'importe quelle machine pourra l'excuter si elle dispose d'une JVM ! Tu n'arrtes pas de nous rabcher byte code par-ci, byte code par-l. . . Mais c'est quoi, au juste ?
Eh bien, un byte code 8 n'est rien d'autre qu'un code intermdiaire entre votre code Java et le code machine. Ce code particulier se trouve dans les chiers prcompils de vos programmes ; en Java, un chier source a pour extension .java et un chier prcompil a l'extension .class : c'est dans ce dernier que vous trouverez du byte code. Je vous invite examiner un chier .class la n de cette partie (vous en aurez au moins un), mais je vous prviens, c'est illisible ! Par contre, vos chiers .java sont de simples chiers texte dont l'extension a t change. Vous pouvez donc les ouvrir, les crer ou encore les mettre jour avec le Bloc-notes de Windows, par exemple. Cela implique que, si vous le souhaitez, vous pouvez crire des programmes Java avec le Bloc-notes ou encore avec Notepad++.
8. Il existe plusieurs types de byte code, mais nous parlons ici de celui cr par Java.

14

VOTRE PREMIER PROGRAMME Reprenons. Vous devez savoir que tous les programmes Java sont composs d'au moins une classe. Cette classe doit contenir une mthode appele main : ce sera le point de dmarrage de notre programme. Une mthode est une suite d'instructions excuter. C'est un morceau de logique de notre programme. Une mthode contient :  un en-tte : celui-ci va tre en quelque sorte la carte d'identit de la mthode ;  un corps : le contenu de la mthode, dlimit par des accolades ;  une valeur de retour : le rsultat que la mthode va retourner.

Vous verrez un peu plus tard qu'un programme n'est qu'une multitude de classes qui s'utilisent l'une l'autre. Mais pour le moment, nous n'allons travailler qu'avec une seule classe.
Je vous avais demand de crer un projet Java ; ouvrez-le (gure 1.16).

Figure

1.16  Mthode principale

Vous voyez la fameuse classe dont je vous parlais ? Ici, elle s'appelle  sdz1 . Vous pouvez voir que le mot class est prcd du mot public, dont nous verrons la signication lorsque nous programmerons des objets. Pour le moment, ce que vous devez retenir, c'est que votre classe est dnie par un mot cl (class), qu'elle a un nom (ici, sdz1) et que son contenu est dlimit par des accolades ({}). Nous crirons nos codes sources entre la mthode main. La syntaxe de cette mthode est toujours la mme :
puli stti void min@tring rgsA{ GGgontenu de votre lsse }

Ce sera entre les accolades de la mthode main que nous crirons nos codes source.
15

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT

Excuse-nous, mais. . . pourquoi as-tu crit  //Contenu de votre classe  et pas  Contenu de votre classe  ?
Bonne question ! Je vous ai dit plus haut que votre programme Java, avant de pouvoir tre excut, doit tre prcompil en byte code. Eh bien, la possibilit de forcer le compilateur ignorer certaines instructions existe ! C'est ce qu'on appelle des commentaires, et deux syntaxes sont disponibles pour commenter son texte.  Il y a les commentaires unilignes : introduits par les symboles //, ils mettent tout ce qui les suit en commentaire, du moment que le texte se trouve sur la mme ligne que les //.
puli stti void min@tring rgsA{ GGn ommentire GGn utre GGinore un utre gei n9est ps un ommentire 3 }

 Il y a les commentaires multilignes : ils sont introduits par les symboles /* et se terminent par les symboles */.
puli stti void min@tring rgsA{ GB n ommentire n utre inore un utre BG gei n9est ps un ommentire 3 }

D'accord, mais a sert quoi ?


C'est simple : au dbut, vous ne ferez que de trs petits programmes. Mais ds que vous aurez pris de la bouteille, leurs tailles et le nombre de classes qui les composeront vont augmenter. Vous serez contents de trouver quelques lignes de commentaires au dbut de votre classe pour vous dire quoi elle sert, ou encore des commentaires dans une mthode qui eectue des choses compliques an de savoir o vous en tes dans vos traitements. . . Il existe en fait une troisime syntaxe, mais elle a une utilit particulire. Elle permettra de gnrer une documentation pour votre programme : une Javadoc (Java Documenta16

VOTRE PREMIER PROGRAMME tion). Je n'en parlerai que trs peu, et pas dans ce chapitre. Nous verrons cela lorsque nous programmerons des objets, mais pour les curieux, je vous conseille le trs bon cours de dworkin sur ce sujet disponible sur le Site du Zro. Prsentation de la Javadoc Code web : 478278 


partir de maintenant et jusqu' ce que nous programmions des interfaces graphiques, nous allons faire ce qu'on appelle des programmes procduraux. Cela signie que le programme s'excutera de faon procdurale, c'est--dire qui s'eectue de haut en bas, une ligne aprs l'autre. Bien sr, il y a des instructions qui permettent de rpter des morceaux de code, mais le programme en lui-mme se terminera une fois parvenu la n du code. Cela vient en opposition la programmation vnementielle (ou graphique) qui, elle, est base sur des vnements (clic de souris, choix dans un menu. . .).

Hello World
Maintenant, essayons de taper le code suivant :
puli stti void min@tring rgsA{ ystemFoutFprint@4rello orld 34AY }

en Java sont suivies d'un point-virgule.

N'oubliez surtout pas le " ; " la n de la ligne ! Toutes les instructions

Une fois que vous avez saisi cette ligne de code dans votre mthode main, il vous faut lancer le programme. Si vous vous souvenez bien de la prsentation faite prcdemment, vous devez cliquer sur la che blanche dans un rond vert (gure 1.17).

Figure

1.17  Bouton de lancement du programme

Si vous regardez dans votre console, dans la fentre du bas sous Eclipse, vous devriez voir la gure 1.18. Expliquons un peu cette ligne de code. Littralement, elle signie  la mthode print() va crire Hello World ! en utilisant l'objet out de la classe System .  System : ceci correspond l'appel d'une classe qui se nomme  System . C'est une classe utilitaire qui permet surtout d'utiliser l'entre et la sortie standard, c'est--dire la saisie clavier et l'achage l'cran.  out : objet de la classe System qui gre la sortie standard. 17

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT

Figure

1.18  Console d'Eclipse

 print : mthode qui crit dans la console le texte pass en paramtre. Si vous mettez plusieurs System.out.print, voici ce qui se passe. Prenons ce code :
ystemFoutFprint@4rello orld 34AY ystemFoutFprint@4wy nme is4AY ystemFoutFprint@4gysoy4AY

Lorsque vous l'excutez, vous devriez voir des chanes de caractres qui se suivent sans saut de ligne. Autrement dit, ceci s'achera dans votre console :
Hello World !My name isCysboy

Je me doute que vous souhaiteriez insrer un retour la ligne pour que votre texte soit plus lisible. . . Pour cela, vous avez plusieurs solutions :  soit vous utilisez un caractre d'chappement, ici \n ;  soit vous utilisez la mthode println() la place de la mthode print(). Donc, si nous reprenons notre code prcdent et que nous appliquons cela, voici ce que a donnerait :
ystemFoutFprint@4rello orld 3 n4AY ystemFoutFprintln@4wy nme is4AY ystemFoutFprintln@4ngysoy4AY

Le rsultat :
Hello World ! My name is Cysboy

Vous pouvez voir que :  lorsque vous utilisez le caractre d'chappement \n, quelle que soit la mthode appele, celle-ci ajoute immdiatement un retour la ligne son emplacement ;  lorsque vous utilisez la mthode println(), celle-ci ajoute automatiquement un retour la ligne la n de la chane passe en paramtre ;  un caractre d'chappement peut tre mis dans la mthode println(). J'en prote au passage pour vous mentionner deux autres caractres d'chappement : 18

VOTRE PREMIER PROGRAMME  \r va insrer un retour chariot, parfois utilis aussi pour les retours la ligne ;  \t va faire une tabulation.

Vous avez srement remarqu que la chane de caractres que l'on ache est entoure de "<chane>". En Java, les guillemets doubles 9 sont des dlimiteurs de chanes de caractres ! Si vous voulez acher un guillemet double dans la sortie standard, vous devrez  l'chapper 10  avec un \, ce qui donnerait : System.out.println("Coucou mon \"chou\" ! ");.
Je vous propose maintenant de passer un peu de temps sur la compilation de vos programmes en ligne de commande. Cette section n'est pas obligatoire, loin de l, mais elle ne peut tre qu'enrichissante.

Compilation en ligne de commande (Windows)


Bienvenue donc aux plus curieux ! Avant de vous apprendre compiler et excuter un programme en ligne de commande, il va vous falloir le JDK (Java SE Development Kit). C'est avec celui-ci que nous aurons de quoi compiler nos programmes. Le ncessaire l'excution des programmes est dans le JRE. . . mais il est galement inclus dans le JDK. Je vous invite donc retourner sur le site d'Oracle et tlcharger ce dernier. Une fois cette opration eectue, il est conseill de mettre jour votre variable d'environnement %PATH%.

Euh. . . quoi ?
Votre variable d'environnement. C'est grce elle que Windows trouve des excutables sans qu'il soit ncessaire de lui spcier le chemin d'accs complet. Vous  enn, Windows  en a plusieurs, mais nous ne nous intresserons qu' une seule. En gros, cette variable contient le chemin d'accs certains programmes. Par exemple, si vous spciez le chemin d'accs un programme X dans votre variable d'environnement et que, par un malheureux hasard, vous n'avez plus aucun raccourci vers X : vous l'avez dnitivement perdu dans les mandres de votre PC. Eh bien vous pourrez le lancer en faisant  Dmarrer Excuter  et en tapant la commande  X.exe  (en partant du principe que le nom de l'excutable est X.exe).

D'accord, mais comment fait-on ? Et pourquoi doit-on faire a pour le JDK ?


9. Il n'est pas rare de croiser le terme anglais quote pour dsigner les guillemets droits. Cela fait en quelque sorte partie du jargon du programmeur. 10. Terme dsignant le fait de dsactiver : ici, dsactiver la fonction du caractre  " .

19

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT J'y arrive. Une fois votre JDK install, ouvrez le rpertoire bin de celui-ci, ainsi que celui de votre JRE. Nous allons nous attarder sur deux chiers. Dans le rpertoire bin de votre JRE, vous devez avoir un chier nomm java.exe. Fichier que vous retrouvez aussi dans le rpertoire bin de votre JDK. C'est grce ce chier que votre ordinateur peut lancer vos programmes par le biais de la JVM. Le deuxime ne se trouve que dans le rpertoire bin de votre JDK, il s'agit de javac.exe 11 . C'est celui-ci qui va prcompiler vos programmes Java en byte code. Alors, pourquoi mettre jour la variable d'environnement pour le JDK ? Eh bien, compiler et excuter en ligne de commande revient utiliser ces deux chiers en leur prcisant o se trouvent les chiers traiter. Cela veut dire que si l'on ne met pas jour la variable d'environnement de Windows, il nous faudrait :  ouvrir l'invite de commande ;  se positionner dans le rpertoire bin de notre JDK ;  appeler la commande souhaite ;  prciser le chemin du chier .java ;  renseigner le nom du chier. Avec notre variable d'environnement mise jour, nous n'aurons plus qu' :  nous positionner dans le dossier de notre programme ;  appeler la commande ;  renseigner le nom du chier Java. Allez dans le  Panneau de configuration  de votre PC ; de l, cliquez sur l'icne  Systme  ; choisissez l'onglet  Avanc  et vous devriez voir en bas un bouton nomm  Variables d'environnement  : cliquez dessus. Une nouvelle fentre s'ouvre. Dans la partie infrieure intitule  Variables systme , cherchez la variable Path. Une fois slectionne, cliquez sur  Modifier . Encore une fois, une fentre, plus petite celle-ci, s'ouvre devant vous. Elle contient le nom de la variable et sa valeur.

Ne changez pas son nom et n'eacez pas son contenu ! Nous allons juste ajouter un chemin d'accs.
Pour ce faire, allez jusqu'au bout de la valeur de la variable, ajoutez-y un point-virgule ( ;) s'il n'y en a pas, et ajoutez alors le chemin d'accs au rpertoire bin de votre JDK, en terminant celui-ci par un point-virgule ! Chez moi, a donne ceci :  C:\Sun\SDK\jdk\bin . Auparavant, ma variable d'environnement contenait, avant mon ajout :
7ystemoot7systemQPY7ystemoot7Y7ystemoot7ystemQPemY

Et maintenant :
7ystemoot7systemQPY7ystemoot7Y7ystemoot7ystemQPemYgXunhujdkinY
11.

Java compiler.

20

VOTRE PREMIER PROGRAMME Validez les changements : vous tes maintenant prts compiler en ligne de commande. Pour bien faire, allez dans le rpertoire de votre premier programme et eacez le .class. Ensuite, faites  Dmarrer > Excuter 12  et tapez  cmd .

Pour rappel, dans l'invite de commande, on se dplace de dossier en dossier grce l'instruction cd. cd <nom du dossier enfant> : pour aller dans un dossier contenu dans celui dans lequel nous nous trouvons. cd .. : pour remonter d'un dossier dans la hirarchie.
Par exemple, lorsque j'ouvre la console, je me trouve dans le dossier C:\toto\titi et mon application se trouve dans le dossier C:\sdz, je fais donc :
d FF d FF d sdz

Aprs de la premire instruction, je me retrouve dans le dossier C:\toto. Grce la deuxime instruction, j'arrive la racine de mon disque. Via la troisime instruction, je me retrouve dans le dossier C:\sdz. Nous sommes maintenant dans le dossier contenant notre chier Java ! Cela dit, nous pouvions condenser cela en :
d FFGFFGsdz

Maintenant, vous pouvez crer votre chier .class en excutant la commande suivante :
jv `nomhepihierFjvb

Si, dans votre dossier, vous avez un chier test.java, compilez-le en faisant : javac test.java. Et si vous n'avez aucun message d'erreur, vous pouvez vrier que le chier test.class est prsent en utilisant l'instruction dir qui liste le contenu d'un rpertoire. Cette tape franchie, vous pouvez lancer votre programme Java en faisant ce qui suit :
jv `nompihierglssnsixtensionb

Ce qui nous donne : java test. Et normalement, le rsultat de votre programme Java s'ache sous vos yeux bahis !

Attention : il ne faut pas mettre l'extension du chier pour le lancer, mais il faut la mettre pour le compiler.
Donc voil : vous avez compil et excut un programme Java en ligne de commande. . . Vous avez pu voir qu'il n'y a rien de vraiment compliqu et, qui sait, vous en aurez peut-tre besoin un jour.
12. Ou encore touche Windows + R.

21

CHAPITRE 1. INSTALLER LES OUTILS DE DVELOPPEMENT

En rsum
          La JVM est le cur de Java. Elle fait fonctionner vos programmes Java, prcompils en byte code. Les chiers contenant le code source de vos programmes Java ont l'extension .java. Les chiers prcompils correspondant vos codes source Java ont l'extension .class. Le byte code est un code intermdiaire entre celui de votre programme et celui que votre machine peut comprendre. Un programme Java, cod sous Windows, peut tre prcompil sous Mac et enn excut sous Linux. Votre machine ne peut pas comprendre le byte code, elle a besoin de la JVM. Tous les programmes Java sont composs d'au moins une classe. Le point de dpart de tout programme Java est la mthode public static void main(String[] args). On peut acher des messages dans la console grce ces instructions :  System.out.println, qui ache un message avec un saut de ligne la n ;  System.out.print, qui ache un message sans saut de ligne.

22

Chapitre

2
Dicult :

Les variables et les oprateurs

ous commenons maintenant srieusement la programmation. Dans ce chapitre, nous allons dcouvrir les variables. On les retrouve dans la quasi-totalit des langages de programmation. Une variable est un lment qui stocke des informations de toute sorte en mmoire : des chires, des rsultats de calcul, des tableaux, des renseignements fournis par l'utilisateur. . . Vous ne pourrez pas programmer sans variables. Il est donc indispensable que je vous les prsente !

23

CHAPITRE 2. LES VARIABLES ET LES OPRATEURS

Les dirents types de variables


Nous allons commencer par dcouvrir comment crer des variables dans la mmoire. Pour cela, il faut les dclarer. Une dclaration de variable se fait comme ceci : <Type de la variable> <Nom de la variable> ; Cette opration se termine toujours par un point-virgule ( ; ) 1 . Ensuite, on l'initialise en entrant une valeur. En Java, nous avons deux types de variables :  des variables de type simple ou  primitif  ;  des variables de type complexe ou des  objets . Ce qu'on appelle des types simples ou types primitifs, en Java, ce sont tout bonnement des nombres entiers, des nombres rels, des boolens ou encore des caractres, et vous allez voir qu'il y a plusieurs faons de dclarer certains de ces types.

Les variables de type numrique


- Le type byte (1 octet) peut contenir les entiers entre 128 et +127.
yte tempertureY temperture a TRY

- Le type short (2 octets) contient les entiers compris entre 32768 et +32767.
short vitessewxY vitessewx a QPHHHY

- Le type int (4 octets) va de 2 109 2 109 (2 et 9 zros derrire. . . ce qui fait dj un joli nombre).
int tempertureoleilY tempertureoleil a ISTHHHHHY

Remarquez qu'ici, la temprature est exprime en kelvins. - Le type long (8 octets) peut aller de 9 1018 9 1018 (encore plus gros. . .).
long nneevumiereY nneevumiere a WRTHUHHHHHHHHHHHY

- Le type float (4 octets) est utilis pour les nombres avec une virgule ottante.
flot piY pi a QFIRISWPTSQfY
1. Comme toutes les instructions de ce langage.

24

LES DIFFRENTS TYPES DE VARIABLES Ou encore :


flot nomreY nomre a PFHfY

Vous remarquerez que nous ne mettons pas une virgule, mais un point ! Et vous remarquerez aussi que mme si le nombre en question est rond, on crit .0 derrire celui-ci, le tout suivi de  f .
- Le type double (8 octets) est identique float, si ce n'est qu'il contient plus de chires derrire la virgule et qu'il n'a pas de suxe.
doule divisionY division a HFQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRY

Nous avons aussi des variables stockant un caractre


- Le type char contient UN caractre stock entre apostrophes ( ' ' ), comme ceci :
hr rtereY rtere a 9e9Y

Des variables de type boolen


- Le type boolean, lui, ne peut contenir que deux valeurs : true (vrai) ou false (faux), sans guillemets 2 .
oolen questionY question a trueY

Et aussi le type String


Le type String permet de grer les chanes de caractres, c'est--dire le stockage de texte. Il s'agit d'une variable d'un type plus complexe que l'on appelle objet. Vous verrez que celle-ci s'utilise un peu diremment des variables prcdentes :
tring phrseY phrse a 4iti et qrosminet4Y GGheuxime mthode de dlrtion de type tring tring str a new tring@AY str a 4ne utre hne de rtres4Y GGv troisime
2. Ces valeurs sont natives dans le langage. Il les comprend directement et sait les interprter.

25

CHAPITRE 2. LES VARIABLES ET LES OPRATEURS


tring string a 4ne utre hne4Y GGit une qutrime pour l route tring hine a new tring@4it une de plus 34AY

Attention : String commence par une majuscule ! Et lors de l'initialisation, on utilise ici des guillemets doubles ( " " ).
Cela a t mentionn plus haut : String n'est pas un type de variable, mais un objet. Notre variable est un objet, on parle aussi d'une instance : ici, une instance de la classe String. Nous y reviendrons lorsque nous aborderons les objets.

On te croit sur parole, mais pourquoi String commence par une majuscule et pas les autres ?
C'est simple : il s'agit d'une convention de nommage. En fait, c'est une faon d'appeler nos classes, nos variables, etc. Il faut que vous essayiez de la respecter au maximum. Cette convention, la voici :  tous vos noms de classes doivent commencer par une majuscule ;  tous vos noms de variables doivent commencer par une minuscule ;  si le nom d'une variable est compos de plusieurs mots, le premier commence par une minuscule, le ou les autres par une majuscule, et ce, sans sparation ;  tout ceci sans accentuation ! Je sais que la premire classe que je vous ai demand de crer ne respecte pas cette convention, mais je ne voulais pas vous en parler ce moment-l. . . Donc, prsent, je vous demanderai de ne pas oublier ces rgles ! Voici quelques exemples de noms de classes et de variables :
puli lss oto{} puli lss xomre{} puli lss otoititi{} tring hineY tring hinehegrteresY int nomreY int nomrelusqrndY GGFFF

Donc, pour en revenir au pourquoi du comment, je vous ai dit que les variables de type String sont des objets. Les objets sont dnis par une ossature (un squelette) qui est en fait une classe. Ici, nous utilisons un objet String dni par une classe qui s'appelle  String  ; c'est pourquoi String a une majuscule et pas int, float, etc., qui eux ne sont pas dnis par une classe. 26

LES OPRATEURS ARITHMTIQUES

Chose importante : veillez bien respecter la casse (majuscules et minuscules), car une dclaration de CHAR la place de char ou autre chose provoquera une erreur, tout comme une variable de type string la place de String !
Faites donc bien attention lors de vos dclarations de variables. . . Une petite astuce quand mme (enn deux, plutt) : on peut trs bien compacter les phases de dclaration et d'initialisation en une seule phase ! Comme ceci :
int entier flot pi a hr r tring mot a QPY QFIRITfY a 9z9Y a new tring@4gouou4AY

Et lorsque nous avons plusieurs variables d'un mme type, nous pouvons rsumer tout ceci une dclaration :
int nreI a PD nreP a QD nreQ a HY

Ici, toutes les variables sont des entiers, et toutes sont initialises. Avant de nous lancer dans la programmation, nous allons faire un peu de mathmatiques avec nos variables.

Les oprateurs arithmtiques


Ce sont ceux que l'on apprend l'cole primaire. . .   +  : permet d'additionner deux variables numriques (mais aussi de concatner des chanes de caractres ! Ne vous inquitez pas, on aura l'occasion d'y revenir).   -  : permet de soustraire deux variables numriques.   *  : permet de multiplier deux variables numriques.   /  : permet de diviser deux variables numriques (mais je crois que vous aviez devin).   %  : permet de renvoyer le reste de la division entire de deux variables de type numrique ; cet oprateur s'appelle le modulo.

Quelques exemples de calcul


int nreID nrePD nreQY nreI nreP nreQ nreI nreP nreQ a a a a a a GGdlrtion des vriles I C QY GGnreI vut R P B TY GGnreP vut IP nreP G nreIY GGnreQ vut Q S 7 PY GGnreI vut ID r S a P B P C I WW 7 VY GGnreP vut QD r WW a V B IP C Q T 7 QY GGlD nreQ vut HD r il n9y ps de reste

27

CHAPITRE 2. LES VARIABLES ET LES OPRATEURS Ici, nous voyons bien que nous pouvons aecter des rsultats d'oprations sur des nombres nos variables, mais aussi aecter des rsultats d'oprations sur des variables de mme type.

Je me doute bien que le modulo est assez dicile assimiler. Voici une utilisation assez simple : pour vrier qu'un entier est pair, il sut de vrier que son modulo 2 renvoie 0.
Maintenant, voici quelque chose que les personnes qui n'ont jamais programm ont du mal intgrer. Je garde la mme dclaration de variables que ci-dessus.
int nreID nrePD nreQY nreI a nreP a nreQ a HY nreI a nreI a a P nreP a nreP a nreQ a nreQ a nreI a nreI a nreI C IY nreI C IY nreIY nreP B PY nrePY nreQ G nreQY nreQY nreI E IY GGdlrtion des vriles GGinitilistion

GGnreI a luiEmmeD don H C I ab nreI a I GGnreI a I @fF iEdessusAD mintenntD nreI a I C I GGnreP GGnreP GGnreQ GGnreQ GGnreI GGnreI a a a a a a nreI a P P ab nreP a P B P a R nreP a R R G R a I nreQ a I I E I a H

Et l aussi, il existe une syntaxe qui raccourcit l'criture de ce genre d'oprations. Regardez bien :
nreI a nreI C IY nreI Ca IY nreICCY CCnreIY

Les trois premires syntaxes correspondent exactement la mme opration. La troisime sera certainement celle que vous utiliserez le plus, mais elle ne fonctionne que pour augmenter d'une unit la valeur de nbre1 ! Si vous voulez augmenter de 2 la valeur d'une variable, utilisez les deux syntaxes prcdentes. On appelle cette cela l'incrmentation. La dernire fait la mme chose que la troisime, mais il y a une subtilit dont nous reparlerons dans le chapitre sur les boucles. Pour la soustraction, la syntaxe est identique :
nreI a nreI E IY nreI Ea IY nreIEEY EEnreIY

Mme commentaire que pour l'addition, sauf qu'ici, la troisime syntaxe s'appelle la dcrmentation. 28

LES OPRATEURS ARITHMTIQUES Les raccourcis pour la multiplication fonctionnent de la mme manire ; regardez plutt :
nreI nreI nreI nreI a nreI B PY Ba PY a nreI G PY Ga PY

Trs important :

on ne peut faire du traitement arithmtique que sur des variables de mme type sous peine de perdre de la prcision lors du calcul. On ne s'amuse pas diviser un int par un float, ou pire, par un char ! Ceci est valable pour tous les oprateurs arithmtiques et pour tous les types de variables numriques. Essayez de garder une certaine rigueur pour vos calculs arithmtiques.

Voici les raisons de ma mise en garde. Comme je vous l'ai dit plus haut, chaque type de variable a une capacit dirente et, pour faire simple, nous allons comparer nos variables dirents rcipients. Une variable de type :  byte correspondrait un d coudre, elle ne peut pas contenir grand-chose ;  int serait un verre, c'est dj plus grand ;  double serait un baril. Pou, on en met l-dedans. . . partir de l, ce n'est plus qu'une question de bon sens. Vous devez facilement constater qu'il est possible de mettre le contenu d'un d coudre dans un verre ou un baril. Par contre, si vous versez le contenu d'un baril dans un verre. . . il y en a plein par terre ! Ainsi, si nous aectons le rsultat d'une opration sur deux variables de type double dans une variable de type int, le rsultat sera de type int et ne sera donc pas un rel mais un entier. Pour acher le contenu d'une variable dans la console, appelez l'instruction System.out.println(maVariable);, ou encore System.out.print(maVariable);. Je suppose que vous voudriez aussi mettre du texte en mme temps que vos variables. . . Eh bien sachez que l'oprateur  +  sert aussi d'oprateur de concatnation, c'est--dire qu'il permet de mlanger du texte brut et des variables. Voici un exemple d'achage avec une perte de prcision :
doule nreI a IHD nreP a QY int resultt a @intA@nreI G nrePAY ystemFoutFprintln@4ve rsultt est a 4 C resulttAY

Sachez aussi que vous pouvez tout fait mettre des oprations dans un achage, comme ceci : System.out.print("Rsultat = " + nbre1/nbre2); (le plus joue ici le rle d'oprateur de concatnation) ; ceci vous permet d'conomiser une variable et par consquent de la mmoire.
29

CHAPITRE 2. LES VARIABLES ET LES OPRATEURS Cependant, pour le bien de ce chapitre, nous n'allons pas utiliser cette mthode. Vous allez constater que le rsultat ach est 3 au lieu de 3.33333333333333. . . Et je pense que ceci vous intrigue : int resultat = (int)(nbre1 / nbre2);. Avant que je ne vous explique, remplacez la ligne cite ci-dessus par : int resultat = nbre1 / nbre2;. Vous allez voir qu'Eclipse n'aime pas du tout ! Pour comprendre cela, nous allons voir les conversions.

Les conversions, ou  cast 


Comme expliqu plus haut, les variables de type double contiennent plus d'informations que les variables de type int. Ici, il va falloir couter comme il faut. . . heu, pardon : lire comme il faut ! Nous allons voir un truc super important en Java. Ne vous en dplaise, vous serez amens convertir des variables. D'un type int en type float :
int i a IPQY flot j a @flotAiY

D'un type int en double :


int i a IPQY doule j a @douleAiY

Et inversement :
doule i a IFPQY doule j a PFWWWWWWWY int k a @intAiY GGk vut I k a @intAjY GGk vut P

Ce type de conversion s'appelle une conversion d'ajustement, ou cast de variable. Vous l'avez vu : nous pouvons passer directement d'un type int un type double. L'inverse, cependant, ne se droulera pas sans une perte de prcision. En eet, comme vous avez pu le constater, lorsque nous castons un double en int, la valeur de ce double est tronque, ce qui signie que l'int en question ne prendra que la valeur entire du double, quelle que soit celle des dcimales. Pour en revenir notre problme de tout l'heure, il est aussi possible de caster le rsultat d'une opration mathmatique en la mettant entre  ()  et en la prcdant du type de cast souhait. Donc : 30

LES CONVERSIONS, OU  CAST 


doule nreI a IHD nreP a QY int resultt a @intA@nreI G nrePAY ystemFoutFprintln@4ve rsultt est a 4 C resulttAY

Voil qui fonctionne parfaitement. Pour bien faire, vous devriez mettre le rsultat de l'opration en type double. Et si on fait l'inverse : si nous dclarons deux entiers et que nous mettons le rsultat dans un double ? Voici une possibilit :
int nreI a QD nreP a PY doule resultt a nreI G nrePY ystemFoutFprintln@4ve rsultt est a 4 C resulttAY

Vous aurez 1 comme rsultat. Je ne caste pas ici, car un double peut contenir un int. En voici une autre :
int nreI a QD nreP a PY doule resultt a @douleA@nreI G nrePAY ystemFoutFprintln@4ve rsultt est a 4 C resulttAY

Idem. . . An de comprendre pourquoi, vous devez savoir qu'en Java, comme dans d'autres langages d'ailleurs, il y a la notion de priorit d'opration ; et l, nous en avons un trs bon exemple !

Sachez que l'aectation, le calcul, le cast, le test, l'incrmentation. . . toutes ces choses sont des oprations ! Et Java les fait dans un certain ordre, il y a des priorits.
Dans le cas qui nous intresse, il y a trois oprations :  un calcul ;  un cast sur le rsultat de l'opration ;  une aectation dans la variable resultat. Eh bien, Java excute notre ligne dans cet ordre ! Il fait le calcul (ici 3/2), il caste le rsultat en double, puis il l'aecte dans notre variable resultat. Vous vous demandez srement pourquoi vous n'avez pas 1.5. . . C'est simple : lors de la premire opration de Java, la JVM voit un cast eectuer, mais sur un rsultat de calcul. La JVM fait ce calcul (division de deux int qui, ici, nous donne 1), puis le cast (toujours 1), et aecte la valeur la variable (encore et toujours 1). Donc, pour avoir un rsultat correct, il faudrait caster chaque nombre avant de faire l'opration, comme ceci :
int nreI a QD nreP a PY doule resultt a @douleA@nreIA G @douleA@nrePAY ystemFoutFprintln@4ve rsultt est a 4 C resulttAY GGffihe X ve rsultt est a IFS

31

CHAPITRE 2. LES VARIABLES ET LES OPRATEURS Je ne vais pas trop dtailler ce qui suit 3 ; mais vous allez maintenant apprendre transformer l'argument d'un type donn, int par exemple, en String.
int i a IPY tring j a new tring@AY j a jFvlueyf@iAY

j est donc une variable de type String contenant la chane de caractres 12. Sachez que

ceci fonctionne aussi avec les autres types numriques. Voyons maintenant comment faire marche arrire en partant de ce que nous venons de faire.
int i a IPY tring j a new tring@AY j a jFvlueyf@iAY int k a sntegerFvlueyf@jAFintlue@AY

Maintenant, la variable k de type int contient le nombre 12.

Il existe des quivalents intValue() pour les autres types numriques : floatValue(), doubleValue(). . .

En rsum
 Les variables sont essentielles dans la construction de programmes informatiques.  On aecte une valeur dans une variable avec l'oprateur gal ( = ).  Aprs avoir aect une valeur une variable, l'instruction doit se terminer par un point-virgule ( ; ).  Vos noms de variables ne doivent contenir ni caractres accentus ni espaces et doivent, dans la mesure du possible, respecter la convention de nommage Java.  Lorsque vous eectuez des oprations sur des variables, prenez garde leur type : vous pourriez perdre en prcision.  Vous pouvez caster un rsultat en ajoutant un type devant celui-ci : (int), (double), etc.  Prenez garde aux priorits lorsque vous castez le rsultat d'oprations, faute de quoi ce dernier risque d'tre incorrect.

3. Vous verrez cela plus en dtail dans la partie sur la programmation oriente objet.

32

Chapitre

3
Dicult :

Lire les entres clavier

prs la lecture de ce chapitre, vous pourrez saisir des informations et les stocker dans des variables an de pouvoir les utiliser a posteriori. En fait, jusqu' ce que nous voyions les interfaces graphiques, nous travaillerons en mode console. Donc, an de rendre nos programmes plus ludiques, il est de bon ton de pouvoir interagir avec ceux-ci. Par contre, ceci peut engendrer des erreurs (on parlera d'exceptions, mais ce sera trait plus loin). An de ne pas surcharger le chapitre, nous survolerons ce point sans voir les dirents cas d'erreurs que cela peut engendrer.

33

CHAPITRE 3. LIRE LES ENTRES CLAVIER

La classe Scanner
Je me doute qu'il vous tardait de pouvoir communiquer avec votre application. . . Le moment est enn venu ! Mais je vous prviens, la mthode que je vais vous donner prsente des failles. Je vous fais conance pour ne pas rentrer n'importe quoi n'importe quand. . . Je vous ai dit que vos variables de type String sont en ralit des objets de type String. Pour que Java puisse lire ce que vous tapez au clavier, vous allez devoir utiliser un objet de type Scanner. Cet objet peut prendre dirents paramtres, mais ici nous n'en utiliserons qu'un : celui qui correspond l'entre standard en Java. Lorsque vous faites System.out.println();, je vous rappelle que vous appliquez la mthode println() sur la sortie standard ; ici, nous allons utiliser l'entre standard System.in. Donc, avant d'indiquer Java qu'il faut lire ce que nous allons taper au clavier, nous devrons instancier un objet Scanner. Avant de vous expliquer ceci, crez une nouvelle classe et tapez cette ligne de code dans votre mthode main :
nner s a new nner@ystemFinAY

Vous devez avoir une jolie vague rouge sous le mot Scanner. Cliquez sur la croix rouge sur la gauche et faites un double-clic sur  Import 'Scanner' java.util (gure 3.1). Et l, l'erreur disparat !

Figure

3.1  Importer la classe Scanner

Maintenant, regardez au-dessus de la dclaration de votre classe, vous devriez voir cette ligne :
import jvFutilFnnerY

Voil ce que nous avons fait. Je vous ai dit qu'il fallait indiquer Java o se trouve la classe Scanner. Pour faire ceci, nous devons importer la classe Scanner grce l'instruction import. La classe que nous voulons se trouve dans le package java.util. Un package est un ensemble de classes. En fait, c'est un ensemble de dossiers et de sous-dossiers contenant une ou plusieurs classes, mais nous verrons ceci plus en dtail lorsque nous ferons nos propres packages. Les classes qui se trouvent dans les packages autres que java.lang 1 sont importer la main dans vos classes Java pour pouvoir vous en servir. La faon dont nous avons
1. Package automatiquement import par Java. On y trouve entre autres la classe System.

34

RCUPRER CE QUE VOUS TAPEZ import la classe java.util.Scanner dans Eclipse est trs commode. Vous pouvez aussi le faire manuellement :
GGgei import GGgei import importe l lsse nner du pkge jvFutil jvFutilFnnerY importe toutes les lsses du pkge jvFutil jvFutilFBY

Rcuprer ce que vous tapez


Voici l'instruction pour permettre Java de rcuprer ce que vous avez saisi pour ensuite l'acher :
nner s a new nner@ystemFinAY ystemFoutFprintln@4euillez sisir un mot X4AY tring str a sFnextvine@AY ystemFoutFprintln@4ous vez sisi X 4 C strAY

Une fois l'application lance, le message que vous avez crit auparavant s'ache dans la console, en bas d'Eclipse. Pensez cliquer dans la console an que ce que vous saisissez y soit crit et que Java puisse rcuprer ce que vous avez inscrit (gure 3.2) !

Figure

3.2  Saisie utilisateur dans la console

Si vous remplacez la ligne de code qui rcupre une chane de caractres comme suit :
nner s a new nner@ystemFinAY ystemFoutFprintln@4euillez sisir un nomre X4AY int str a sFnextsnt@AY ystemFoutFprintln@4ous vez sisi le nomre X 4 C strAY

. . . vous devriez constater que lorsque vous introduisez votre variable de type Scanner et que vous introduisez le point permettant d'appeler des mthodes de l'objet, Eclipse vous propose une liste de mthodes associes cet objet 2 ; de plus, lorsque vous commencez taper le dbut de la mthode nextInt(), le choix se restreint jusqu' ne laisser que cette seule mthode. Excutez et testez ce programme : vous verrez qu'il fonctionne la perfection. Sauf. . . si vous saisissez autre chose qu'un nombre entier !
2. Ceci s'appelle l'autocompltion.

35

CHAPITRE 3. LIRE LES ENTRES CLAVIER Vous savez maintenant que pour lire un int, vous devez utiliser nextInt(). De faon gnrale, dites-vous que pour rcuprer un type de variable, il vous sut d'appeler next<Type de variable commenant par une majuscule> 3 .
nner s a new nner@ystemFinAY int i a sFnextsnt@AY doule d a sFnexthoule@AY long l a sFnextvong@AY yte a sFnextfyte@AY GGitF

la classe Scanner : il s'agit du type char. Voici comment on pourrait rcuprer un caractre :
ystemFoutFprintln@4isissez une lettre X4AY nner s a new nner@ystemFinAY tring str a sFnextvine@AY hr r a strFhret@HAY ystemFoutFprintln@4ous vez sisi le rtre X 4 C rAY

Attention : il y a un type de variables primitives qui n'est pas pris en compte par

Qu'avons-nous fait ici ? Nous avons rcupr une chane de caractres, puis utilis une mthode de l'objet String (ici, charAt(0) ) an de rcuprer le premier caractre saisi. Mme si vous tapez une longue chane de caractres, l'instruction charAt(0) 4 ne renverra que le premier caractre. Jusqu' ce qu'on aborde les exceptions, je vous demanderai d'tre rigoureux et de faire attention ce que vous attendez comme type de donnes an d'utiliser la mthode correspondante. Une prcision s'impose, toutefois : la mthode nextLine() rcupre le contenu de toute la ligne saisie et replace la  tte de lecture  au dbut d'une autre ligne. Par contre, si vous avez invoqu une mthode comme nextInt(), nextDouble() et que vous invoquez directement aprs la mthode nextLine(), celle-ci ne vous invitera pas saisir une chane de caractres : elle videra la ligne commence par les autres instructions. En eet, celles-ci ne repositionnent pas la tte de lecture, l'instruction nextLine() le fait leur place. Pour faire simple, ceci :
import jvFutilFnnerY puli lss win { puli stti void min@tring rgsA{ nner s a new nner@ystemFinAY ystemFoutFprintln@4isissez un entier X 4AY int i a sFnextsnt@AY ystemFoutFprintln@4isissez une hne X 4AY tring str a sFnextvine@AY
3. Rappelez-vous de la convention de nommage Java ! 4. Vous devez vous demander pourquoi charAt(0) et non charAt(1) : nous aborderons ce point lorsque nous verrons les tableaux. . .

36

RCUPRER CE QUE VOUS TAPEZ


ystemFoutFprintln@4psx 3 4AY

. . . ne vous demandera pas de saisir une chane et achera directement  Fin . Pour pallier ce problme, il sut de vider la ligne aprs les instructions ne le faisant pas automatiquement :
import jvFutilFnnerY puli lss win { puli stti void min@tring rgsA{ nner s a new nner@ystemFinAY ystemFoutFprintln@4isissez un entier X 4AY int i a sFnextsnt@AY ystemFoutFprintln@4isissez une hne X 4AY GGyn vide l ligne vnt d9en lire une utre sFnextvine@AY tring str a sFnextvine@AY ystemFoutFprintln@4psx 3 4AY } }

En rsum
 La lecture des entres clavier se fait via l'objet Scanner.  Ce dernier se trouve dans le package java.util que vous devrez importer.  Pour pouvoir rcuprer ce vous allez taper dans la console, vous devrez initialiser l'objet Scanner avec l'entre standard, System.in.  Il y a une mthode de rcupration de donnes pour chaque type (sauf les char) : nextLine() pour les String, nextInt() pour les int. . .

37

CHAPITRE 3. LIRE LES ENTRES CLAVIER

38

Chapitre

4
Dicult :

Les conditions

ous abordons ici l'un des chapitres les plus importants : les conditions sont une autre notion fondamentale de la programmation. En eet, ce qui va tre dvelopp ici s'applique normment de langages de programmation, et pas seulement Java. Dans une classe, la lecture et l'excution se font de faon squentielle, c'est--dire ligne par ligne. Avec les conditions, nous allons pouvoir grer dirents cas de gure sans pour autant lire tout le code. Vous vous rendrez vite compte que tous vos projets ne sont que des enchanements et des imbrications de conditions et de boucles (notion que l'on abordera au chapitre suivant). Assez de belles paroles ! Entrons tout de suite dans le vif du sujet.

39

CHAPITRE 4. LES CONDITIONS

La structure if... else


Avant de pouvoir crer et valuer des conditions, vous devez savoir que pour y parvenir, nous allons utiliser ce qu'on appelle des oprateurs logiques. Ceux-ci sont surtout utiliss lors de conditions (si [test] alors [faire ceci]) pour valuer dirents cas possibles. Voici les dirents oprateurs connatre :   ==  : permet de tester l'galit.   !=  : permet de tester l'ingalit.   <  : strictement infrieur.   <=  : infrieur ou gal.   >  : strictement suprieur.   >=  : suprieur ou gal.   &&  : l'oprateur et. Il permet de prciser une condition.   ||  : le ou. Mme combat que le prcdent.   ? :  : l'oprateur ternaire. Pour celui-ci, vous comprendrez mieux avec un exemple qui sera donn vers la n de ce chapitre. Comme je vous l'ai dit dans le chapitre prcdent, les oprations en Java sont soumises des priorits. Tous ces oprateurs se plient cette rgle, de la mme manire que les oprateurs arithmtiques. . . Imaginons un programme qui demande un utilisateur d'entrer un nombre entier relatif (qui peut tre soit ngatif, soit nul, soit positif). Les structures conditionnelles vont nous permettre de grer ces trois cas de gure. La structure de ces conditions ressemble a :
if@GGonditionA { FFF GGixution des instrutions si l ondition est remplie } else { FFF GGixution des instrutions si l ondition n9est ps remplie }

Cela peut se traduire par  si. . . sinon. . . . Le rsultat de l'expression value par l'instruction if sera un boolean, donc soit true, soit false. La portion de code du bloc if ne sera excute que si la condition est remplie. Dans le cas contraire, c'est le bloc de l'instruction else qui le sera. Mettons notre petit exemple en pratique :
int i a IHY if @i ` HA ystemFoutFprintln@4le nomre est ngtif4AY else ystemFoutFprintln@4le nomre est positif4AY

Essayez ce petit code, et vous verrez comment il fonctionne. Dans ce cas, notre classe ache que  le nombre est positif . Expliquons un peu ce qui se passe. 40

LA STRUCTURE IF... ELSE  Dans un premier temps, la condition du if est teste (elle dit si i est strictement infrieur 0). . .  Dans un second temps, vu que celle-ci est fausse, le programme excute le else.

Attends un peu ! Lorsque tu nous as prsent la structure des conditions, tu as mis des accolades et l, tu n'en mets pas. . .
Bien observ. En fait, les accolades sont prsentes dans la structure  normale  des conditions, mais lorsque le code l'intrieur de l'une d'entre elles n'est compos que d'une seule ligne, les accolades deviennent facultatives. Comme nous avons l'esprit perfectionniste, nous voulons que notre programme ache  le nombre est nul  lorsque i est gal 0 ; nous allons donc ajouter une condition. Comment faire ? La condition du if est remplie si le nombre est strictement ngatif, ce qui n'est pas le cas ici puisque nous allons le mettre 0. Le code contenu dans la clause else est donc excut si le nombre est gal ou strictement suprieur 0. Il nous sut d'ajouter une condition l'intrieur de la clause else, comme ceci :
int i a HY if @i ` HA { ystemFoutFprintln@4ge nomre est ngtif 34AY } else { if@i aa HA ystemFoutFprintln@4ge nomre est nul 34AY else } ystemFoutFprintln@4ge nomre est positif 34AY

Maintenant que vous avez tout compris, je vais vous prsenter une autre faon d'crire ce code, avec le mme rsultat : on ajoute juste un petit sinon si.
int i a HY if @i ` HA ystemFoutFprintln@4ge nomre est ngtif 34AY else if@i b HA ystemFoutFprintln@4ge nomre est positif 34AY else ystemFoutFprintln@4ge nomre est nul 34AY

Alors ? Explicite, n'est-ce pas ? 41

CHAPITRE 4. LES CONDITIONS   


i est strictement ngatif excution du code. i est strictement positif excution du code. sinon i est forcment nul excution du code.
si sinon si

Il faut absolument donner une condition au else

if

pour qu'il fonctionne.

Ici, je vais trs fortement insister sur un point : regardez l'achage du code et remarquez le petit dcalage entre le test et le code excuter. On appelle cela l'indentation ! Pour vous reprer dans vos futurs programmes, cela sera trs utile. Imaginez deux secondes que vous avez un programme de 700 lignes avec 150 conditions, et que tout est crit le long du bord gauche. Il sera dicile de distinguer les tests du code. Vous n'tes pas obligs de le faire, mais je vous assure que vous y viendrez.

Avant de passer la suite, vous devez savoir qu'on ne peut pas tester l'galit de chanes de caractres ! Du moins, pas comme je vous l'ai montr ci-dessus. Nous aborderons ce point plus tard.

Les conditions multiples


Derrire ce nom barbare se cachent simplement plusieurs tests dans une instruction if (ou else if). Nous allons maintenant utiliser les oprateurs logiques que nous avons vus au dbut en vriant si un nombre donn appartient un intervalle connu. Par exemple, on va vrier si un entier est compris entre 50 et 100.
int i a SVY if@i ` IHH 88 i b SHA ystemFoutFprintln@4ve nomre est ien dns l9intervlleF4AY else ystemFoutFprintln@4ve nomre n9est ps dns l9intervlleF4AY

Nous avons utilis l'oprateur &&. La condition de notre if est devenue : si i est infrieur 100 et suprieur 50, alors la condition est remplie.

Avec l'oprateur &&, la clause est remplie si et seulement si les conditions la constituant sont toutes remplies ; si l'une des conditions n'est pas vrie, la clause sera considre comme fausse.
Cet oprateur vous initie la notion d'intersection d'ensembles. Ici, nous avons deux conditions qui dnissent un ensemble chacune :  i < 100 dnit l'ensemble des nombres infrieurs 100 ;  i > 50 dnit l'ensemble des nombres suprieurs 50. 42

LA STRUCTURE SWITCH L'oprateur && permet de faire l'intersection de ces ensembles. La condition regroupe donc les nombres qui appartiennent ces deux ensembles, c'est--dire les nombres de 51 99 inclus. Rchissez bien l'intervalle que vous voulez dnir. Voyez ce code :
int i a SVY if@i ` IHH 88 i b IHHA ystemFoutFprintln@4ve nomre est ien dns l9intervlleF4AY else ystemFoutFprintln@4ve nomre n9est ps dns l9intervlleF4AY

Ici, la condition ne sera jamais remplie, car je ne connais aucun nombre qui soit la fois plus petit et plus grand que 100 ! Reprenez le code prcdent et remplacez l'oprateur && par || 1 . l'excution du programme et aprs plusieurs tests de valeur pour i, vous pourrez vous apercevoir que tous les nombres remplissent cette condition, sauf 100.

La structure switch
Le switch est surtout utilis lorsque nous voulons des conditions  la carte . Prenons l'exemple d'une interrogation comportant deux questions : pour chacune d'elles, on peut obtenir uniquement 0 ou 10 points, ce qui nous donne au nal trois notes et donc trois apprciations possibles, comme ceci.  0/20 : tu peux revoir ce chapitre, petit Zro !  10/20 : je crois que tu as compris l'essentiel ! Viens relire ce chapitre l'occasion.  20/20 : bravo ! Dans ce genre de cas, on utilise un switch pour viter des else if rptition et pour allger un peu le code. Je vais vous montrer comment se construit une instruction switch ; puis nous allons l'utiliser tout de suite aprs.

Syntaxe
swith @GBrileBGA { se GBergumentBGX GBetionBGY rekY defultX GBetionBGY }

Voici les oprations qu'eectue cette expression.  La classe value l'expression gurant aprs le switch (ici /*Variable*/).  Si la premire languette (case /*Valeur possible de la variable*/:) correspond la valeur de /*Variable*/, l'instruction gurant dans celle-ci sera excute.
1. Petit rappel, il s'agit du ou.

43

CHAPITRE 4. LES CONDITIONS  Sinon, on passe la languette suivante, et ainsi de suite.  Si aucun des cas ne correspond, la classe va excuter ce qui se trouve dans l'instruction default:/*Action*/;. Voyez ceci comme une scurit. Notez bien la prsence de l'instruction break;. Elle permet de sortir du switch si une languette correspond 2 . Voici un exemple de switch que vous pouvez essayer :
int note a IHY GGyn imgine que l note mximle est PH swith @noteA { se HX ystemFoutFprintln@4yuh 34AY rekY se IHX ystemFoutFprintln@4ous vez juste l moyenneF4AY rekY se PHX ystemFoutFprintln@4rfit 34AY rekY defultX ystemFoutFprintln@4sl fut dvntge trvillerF4AY }

Je n'ai crit qu'une ligne de code par instruction empche d'en mettre plusieurs.

case,

mais rien ne vous

Si vous avez essay ce programme en supprimant l'instruction break;, vous avez d vous rendre compte que le switch excute le code contenu dans le case 10:, mais aussi dans tous ceux qui suivent ! L'instruction break; permet de sortir de l'opration en cours. Dans notre cas, on sort de l'instruction switch, mais nous verrons une autre utilit break; dans le chapitre suivant.

L'instruction switch ne prend que des entiers ou des caractres en paramtre. Il est important de le remarquer.

La condition ternaire
Les conditions ternaires sont assez complexes et relativement peu utilises. Je vous les prsente ici titre indicatif.
2. Pour mieux juger de l'utilit de cette instruction, enlevez tous les break; et compilez votre programme. Vous verrez le rsultat. . .

44

LA CONDITION TERNAIRE La particularit des conditions ternaires rside dans le fait que trois oprandes (c'est-dire des variables ou des constantes) sont mis en jeu, mais aussi que ces conditions sont employes pour aecter des donnes une variable. Voici quoi ressemble la structure de ce type de condition :
int x a IHD y a PHY int mx a @x ` yA c y X x Y GGwintenntD mx vut PH

Dcortiquons ce qu'il se passe.  Nous cherchons aecter une valeur notre variable max, mais de l'autre ct de l'oprateur d'aectation se trouve une condition ternaire. . .  Ce qui se trouve entre les parenthses est valu : x est-il plus petit que y ? Donc, deux cas de gure se prolent l'horizon :  si la condition renvoie true (vrai), qu'elle est vrie, la valeur qui se trouve aprs le ? sera aecte ;  sinon, la valeur se trouvant aprs le symbole : sera aecte.  L'aectation est eective : vous pouvez utiliser votre variable max. Vous pouvez galement faire des calculs (par exemple) avant d'aecter les valeurs :
int x a IHD y a PHY int mx a @x ` yA c y B P X x B P Y GGsiD mx vut P B PH don RH

N'oubliez pas que la valeur que vous allez aecter votre variable doit tre du mme type que votre variable. Sachez aussi que rien ne vous empche d'insrer une condition ternaire dans une autre condition ternaire :
int x a IHD y a PHY int mx a @x ` yA c @y ` IHA c y 7 IH X y B P X x Y GGwx vut RH GGs trs file lireFFF GGous pouvez entourer votre deuxime instrution ternire GGde prenthses pour mieux voir mx a @x ` yA c @@y ` IHA c y 7 IH X y B PA X x Y GGwx vut RH

En rsum
 Les conditions vous permettent de n'excuter que certains morceaux de code.  Il existe plusieurs sortes de structures conditionnelles :  la structure if... elseif... else ;  la structure switch... case... default ;  la structure ? :.  Si un bloc d'instructions contient plus d'une ligne, vous devez l'entourer d'accolades an de bien en dlimiter le dbut et la n.  Pour pouvoir mettre une condition en place, vous devez comparer des variables l'aide d'oprateurs logiques. 45

CHAPITRE 4. LES CONDITIONS  Vous pouvez mettre autant de comparaisons renvoyant un boolean que vous le souhaitez dans une condition.  Pour la structure switch, pensez mettre les instructions break; si vous ne souhaitez excuter qu'un seul bloc case.

46

Chapitre

5
Dicult :

Les boucles

e rle des boucles est de rpter un certain nombre de fois les mmes oprations. Tous les programmes, ou presque, ont besoin de ce type de fonctionnalit. Nous utiliserons les boucles pour permettre un programme de recommencer depuis le dbut, pour attendre une action prcise de l'utilisateur, parcourir une srie de donnes, etc. Une boucle s'excute tant qu'une condition est remplie. Nous rutiliserons donc des notions du chapitre prcdent !

47

CHAPITRE 5. LES BOUCLES

La boucle while
Dcortiquons prcisment ce qui se passe dans une boucle. Pour ce faire, nous allons voir comment elle se construit. Une boucle commence par une dclaration : ici while. Cela veut dire, peu de chose prs,  tant que . Puis nous avons une condition : c'est elle qui permet la boucle de s'arrter. Une boucle n'est utile que lorsque nous pouvons la contrler, et donc lui faire rpter une instruction un certain nombre de fois. C'est a que servent les conditions. Ensuite nous avons une ou plusieurs instructions : c'est ce que va rpter notre boucle 1 !
while @GB gondition BGA { GGsnstrutions rpter }

Un exemple concret tant toujours le bienvenu, en voici un. . . D'abord, rchissons  comment notre boucle va travailler . Pour cela, il faut dterminer notre exemple. Nous allons acher  Bonjour, <un prnom> , prnom qu'il faudra taper au clavier ; puis nous demanderons si l'on veut recommencer. Pour cela, il nous faut une variable qui va recevoir le prnom, donc dont le type sera String, ainsi qu'une variable pour rcuprer la rponse. Et l, plusieurs choix s'orent nous : soit un caractre, soit une chane de caractres, soit un entier. Ici, nous prendrons une variable de type char. C'est parti !
GGne vrile vide tring prenomY GGyn initilise elleEi y pour oui hr reponse a 9y9Y GGxotre ojet nnerD n9ouliez ps l9import de jvFutilFnner 3 nner s a new nner@ystemFinAY GGnt que l rponse donne est gle ouiFFF while @reponse aa 9y9A { GGyn ffihe une instrution ystemFoutFprintln@4honnez un prnom X 4AY GGyn rupre le prnom sisi prenom a sFnextvine@AY GGyn ffihe notre phrse ve le prnom ystemFoutFprintln@4fonjour 4 CprenomC 4D omment vsEtu c4AY GGyn demnde si l personne veut fire un utre essi ystemFoutFprintln@4oulezEvous ressyer c @yGxA4AY GGyn rupre l rponse de l9utilisteur reponse a sFnextvine@AFhret@HAY }
1. Il peut mme y avoir des boucles dans une boucle.

48

LA BOUCLE WHILE

ystemFoutFprintln@4eu revoirFFF4AY GGpin de l oule

Vous avez d cligner des yeux en lisant  reponse = sc.nextLine().charAt(0); . Rappelez-vous comment on rcupre un char avec l'objet Scanner : nous devons rcuprer un objet String et ensuite prendre le premier caractre de celui-ci ! Eh bien cette syntaxe est une contraction de ce que je vous avais fait voir auparavant. Dtaillons un peu ce qu'il se passe. Dans un premier temps, nous avons dclar et initialis nos variables. Ensuite, la boucle value la condition qui nous dit : tant que la variable reponse contient  O , on excute la boucle. Celle-ci contient bien le caractre  O , donc nous entrons dans la boucle. Puis l'excution des instructions suivant l'ordre dans lequel elles apparaissent dans la boucle a lieu. la n, c'est--dire l'accolade fermante de la boucle, le compilateur nous ramne au dbut de la boucle.

Cette boucle n'est excute que lorsque la condition est remplie : ici, nous avons initialis la variable reponse  O  pour que la boucle s'excute. Si nous ne l'avions pas fait, nous n'y serions jamais entrs. Normal, puisque nous testons la condition avant d'entrer dans la boucle !
Voil. C'est pas mal, mais il faudrait forcer l'utilisateur ne taper que  O  ou  N . Comment faire ? C'est trs simple : avec une boucle ! Il sut de forcer l'utilisateur entrer soit  N  soit  O  avec un while ! Attention, il nous faudra rinitialiser la variable reponse  ' '  2 . Il faudra donc rpter la phase  Voulez-vous ressayer ?  tant que la rponse donne n'est pas  O  ou  N  : voil, tout y est. Voici notre programme dans son intgralit :
tring prenomY hr reponse a 9y9Y nner s a new nner@ystemFinAY while @reponse aa 9y9A { ystemFoutFprintln@4honnez un prnom X 4AY prenom a sFnextvine@AY ystemFoutFprintln@4fonjour 4 CprenomC 4D omment vsEtu c4AY GGns D nous n9entrerions ps dns l deuxime oule reponse a 9 9Y GGnt que l rponse n9est ps y ou xD on repose l question while@reponse 3a 9y9 88 reponse 3a 9x9A { GGyn demnde si l personne veut fire un utre essi ystemFoutFprintln@4oulezEvous ressyer c @yGxA4AY reponse a sFnextvine@AFhret@HAY
2. Caractre vide.

49

CHAPITRE 5. LES BOUCLES


} } ystemFoutFprintln@4eu revoirFFF4AY

Copier ce code Code web : 856542  Vous pouvez tester ce code (c'est d'ailleurs vivement conseill) : vous verrez que si vous n'entrez pas la bonne lettre, le programme vous posera sans cesse sa question (gure 5.1) !

Figure

5.1  Test de la boucle

Attention crire correctement vos conditions et bien vrier vos variables dans vos while, et dans toutes vos boucles en gnral. Sinon c'est le drame ! Essayez d'excuter le programme prcdent sans la rinitialisation de la variable reponse, et vous verrez le rsultat. . . On n'entre jamais dans la deuxime boucle, car reponse = 'O' (puisque initialise ainsi au dbut du programme). L, vous ne pourrez jamais changer sa valeur. . . le programme ne s'arrtera donc jamais ! On appelle a une boucle innie, et en voici un autre exemple.
int a ID a ISY while @ ` A { ystemFoutFprintln@4ouou 4 CC 4 fois 334AY }

Si vous lancez ce programme, vous allez voir une quantit astronomique de coucou 1 fois !!. Nous aurions d ajouter une instruction dans le bloc d'instructions de notre while pour changer la valeur de a chaque tour de boucle, comme ceci :
int a ID a ISY while @ ` A

50

LA BOUCLE WHILE
{ }

ystemFoutFprintln@4ouou 4 CC 4 fois 334AY CCY

Ce qui nous donnerait comme rsultat la gure 5.2.

Figure

5.2  Correction de la boucle innie

Une petite astuce : lorsque vous n'avez qu'une instruction dans votre boucle, vous pouvez enlever les accolades, car elles deviennent superues, tout comme pour les instructions if, else if ou else.
Vous auriez aussi pu utiliser cette syntaxe :
int a ID a ISY while @CC ` A ystemFoutFprintln@4ouou 4 CC 4 fois 334AY

Souvenez-vous de ce dont je vous parlais au chapitre prcdent sur la priorit des oprateurs. Ici, l'oprateur  <  a la priorit sur l'oprateur d'incrmentation  ++ . Pour faire court, la boucle while teste la condition et ensuite incrmente la variable a. Par contre, essayez ce code :
int a ID a ISY while @CC ` A ystemFoutFprintln@4ouou 4 CC 4 fois 334AY

Vous devez remarquer qu'il y a un tour de boucle en moins ! Eh bien avec cette syntaxe, l'oprateur d'incrmentation est prioritaire sur l'oprateur d'ingalit (ou d'galit), c'est--dire que la boucle incrmente la variable a, et ce n'est qu'aprs l'avoir fait qu'elle teste la condition ! 51

CHAPITRE 5. LES BOUCLES

La boucle do... while


Puisque je viens de vous expliquer comment fonctionne une boucle while, je ne vais pas vraiment m'attarder sur la boucle do... while. En eet, ces deux boucles ne sont pas cousines, mais plutt surs. Leur fonctionnement est identique deux dtails prs.
do{ GGllllllll }while@ ` AY

Premire dirence
La boucle do... while s'excutera au moins une fois, contrairement sa sur. C'est--dire que la phase de test de la condition se fait la n, car la condition se met aprs le while.

Deuxime dirence
C'est une dirence de syntaxe, qui se situe aprs la condition du while. Vous voyez la dirence ? Oui ? Non ? Il y a un  ;  aprs le while. C'est tout ! Ne l'oubliez cependant pas, sinon le programme ne compilera pas. Mis part ces deux lments, ces boucles fonctionnent exactement de la mme manire. D'ailleurs, refaisons notre programme prcdent avec une boucle do... while.
tring prenom a new tring@AY GGs esoin d9initiliser X on entre u moins une fois dns l oule 3 hr reponse a 9 9Y nner s a new nner@ystemFinAY do{ ystemFoutFprintln@4honnez un prnom X 4AY prenom a sFnextvine@AY ystemFoutFprintln@4fonjour 4 CprenomC 4D omment vsEtu c4AY do{ ystemFoutFprintln@4oulezEvous ressyer c @yGxA4AY reponse a sFnextvine@AFhret@HAY }while@reponse 3a 9y9 88 reponse 3a 9x9AY }while @reponse aa 9y9AY ystemFoutFprintln@4eu revoirFFF4AY

Vous voyez donc que ce code ressemble beaucoup celui utilis avec la boucle while, 52

LA BOUCLE FOR mais il comporte une petite subtilit : ici, plus besoin de rinitialiser la variable reponse, puisque de toute manire, la boucle s'excutera au moins une fois !

La boucle for
Cette boucle est un peu particulire puisqu'elle prend tous ses attributs dans sa condition et agit en consquence. Je m'explique : jusqu'ici, nous avions fait des boucles avec :  dclaration d'une variable avant la boucle ;  initialisation de cette variable ;  incrmentation de celle-ci dans la boucle. Eh bien on met tout a dans la condition de la boucle for 3 , et c'est tout. Mais je sais bien qu'un long discours ne vaut pas un exemple, alors voici une boucle for sous vos yeux bahis :
for@int i a IY i `a IHY iCCA { ystemFoutFprintln@4oii l ligne 4CiAY }

Ce qui donne la gure 5.3.

Figure

5.3  Test de boucle for

Vous aurez srement remarqu la prsence des  ;  dans la condition pour la sparation des champs. Ne les oubliez surtout pas, sinon le programme ne compilera pas. Nous pouvons aussi inverser le sens de la boucle, c'est--dire qu'au lieu de partir de 0 pour aller 10, nous allons commencer 10 pour atteindre 0 :
for@int i a IHY i ba HY iEEA ystemFoutFprintln@4sl reste 4CiC4 ligne@sA rire4AY
3. Il existe une autre syntaxe pour la boucle for depuis le JDK 1.5. Nous la verrons lorsque nous aborderons les tableaux.

53

CHAPITRE 5. LES BOUCLES On obtient la gure 5.4.

Figure

5.4  Boucle for avec dcrmentation

Pour simplier, la boucle for est un peu le condens d'une boucle while dont le nombre de tours se dtermine via un incrment. Nous avons un nombre de dpart, une condition qui doit tre remplie pour excuter une nouvelle fois la boucle et une instruction de n de boucle qui incrmente notre nombre de dpart. Remarquez que rien ne nous empche de cumuler les dclarations, les conditions et les instructions de n de boucle :
for@int i a HD j a PY @i ` IH 88 j ` TAY iCCD jCaPA{ ystemFoutFprintln@4i a 4 C i C 4D j a 4 C jAY }

Ici, cette boucle n'eectuera que deux tours puisque la condition (i < 10 && j < 6) est remplie ds le deuxime tour, la variable j commenant 2 et tant incrmente de deux chaque tour de boucle.

En rsum
 Les boucles vous permettent simplement d'eectuer des tches rptitives.  Il existe plusieurs sortes de boucles :  la boucle while(condition){...} value la condition puis excute ventuellement un tour de boucle (ou plus) ;  la boucle do{...}while(condition); fonctionne exactement comme la prcdente, mais eectue un tour de boucle quoi qu'il arrive ;  la boucle for permet d'initialiser un compteur, une condition et un incrment dans sa dclaration an de rpter un morceau de code un nombre limit de fois.  Tout comme les conditions, si une boucle contient plus d'une ligne de code excuter, vous devez l'entourer d'accolades an de bien en dlimiter le dbut et la n.

54

Chapitre

6
Dicult :

TP : conversion Celsius - Fahrenheit

oil un trs bon petit TP qui va vous permettre de mettre en uvre toutes les notions que vous avez vues jusqu'ici :  les variables ;  les conditions ;  les boucles ;  votre gnial cerveau. Accrochez-vous, car je vais vous demander de penser des tonnes de choses, et vous serez tout seuls. Lchs dans la nature. . . Mais non je plaisante, je vais vous guider un peu. ;-)

55

CHAPITRE 6. TP : CONVERSION CELSIUS - FAHRENHEIT

laboration
Voici le programme que nous allons devoir raliser :  le programme demande quelle conversion nous souhaitons eectuer, Celsius vers Fahrenheit ou l'inverse ;  on n'autorise que les modes de conversion dnis dans le programme (un simple contrle sur la saisie fera l'aaire) ;  enn, on demande la n l'utilisateur s'il veut faire une nouvelle conversion, ce qui signie que l'on doit pouvoir revenir au dbut du programme ! Avant de vous lancer dans la programmation proprement parler, je vous conseille fortement de rchir votre code. . . sur papier. Rchissez ce qu'il vous faut comme nombre de variables, les types de variables, comment va se drouler le programme, les conditions et les boucles utilises. . . toutes ns utiles, voici la formule de conversion pour passer des degrs Celsius en 9 degrs Fahrenheit : F = 5 C + 32 ; pour l'opration inverse, c'est comme ceci : (F 32)5 . C= 9 Voici un aperu de ce que je vous demande (gure 6.1).

Figure

6.1  Rendu du TP

Je vais galement vous donner une fonction toute faite qui vous permettra ventuellement d'arrondir vos rsultats. Je vous expliquerai le fonctionnement des fonctions dans deux chapitres. Tant qu' prsent, c'est facultatif, vous pouvez trs bien ne pas vous en servir. Pour ceux qui souhaitent tout de mme l'utiliser, la voici :
puli stti doule rrondi@doule eD int fA { return @douleA @ @intA @e B wthFpow@IHD fA C FSAA G wthFpow@IHD fAY }

56

CORRECTION Elle est placer entre les deux accolades fermantes de votre classe (gure 6.2).

Figure

6.2  Emplacement de la fonction

Voici comment utiliser cette fonction : imaginez que vous avez la variable faren arrondir, et que le rsultat obtenu est enregistr dans une variable arrondFaren ; vous procderez comme suit :
rrondpren a rrondi@frenDIAY GGour un hiffre prs l virgule rrondpren a rrondi@frenD PAYGGour deux hiffres prs l virguleD etF

Quelques dernires recommandations : essayez de bien indenter votre code ! Prenez votre temps. Essayez de penser tous les cas de gure. . . Maintenant vos papiers, crayons, neurones, claviers. . . et bon courage !

Correction
C'est ni ! Il est temps de passer la correction de ce premier TP. a va ? Pas trop mal la tte ? Je me doute qu'il a d y avoir quelques tubes d'aspirine vids. . . Vous allez voir qu'en dnitive, ce TP n'tait pas si compliqu que a. Surtout, n'allez pas croire que ma correction est parole d'vangile. . . Il y avait direntes manires d'obtenir le mme rsultat. Voici tout de mme une des solutions possibles.
Stop !

import jvFutilFnnerY lss dzI { puli stti void min@tring rgsA { GGxotre ojet nner nner s a new nner@ystemFinAY

57

CHAPITRE 6. TP : CONVERSION CELSIUS - FAHRENHEIT

GGinitilistion des vriles doule gonvertirD onvertitaHY hr reponsea9 9D mode a 9 9Y ystemFoutFprintln@4gyxisi hiq givs i hiq perixris4AY ystemFoutFprintln@4EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE4AY do{GGtnt que reponse a yGGoule priniple do{GGtnt que reponse n9est ps y ou x mode a 9 9Y ystemFoutFprintln@4ghoisissez le mode de onversion X 4AY ystemFoutFprintln@4I E gonvertisseur gelsius E phrenheit4AY ystemFoutFprintln@4P E gonvertisseur phrenheit E gelsius 4AY mode a sFnextvine@AFhret@HAY if@mode 3a 9I9 88 mode 3a 9P9A ystemFoutFprintln@4wode inonnuD veuillez ritrer votre hoixF4AY }while @mode 3a 9I9 88 mode 3a 9P9AY GGsisie de l temprture onvertir ystemFoutFprintln@4emprture onvertir X4AY gonvertir a sFnexthoule@AY GGensez vider l ligne lue sFnextvine@AY GGelon le modeD on lule diffremment et on ffihe le rsultt if@mode aa 9I9A{ onvertit a @@WFHGSFHA B gonvertirA C QPFHY ystemFoutFprint@gonvertir C 4 g orrespond X 4AY ystemFoutFprintln@rrondi@onvertitD PA C 4 pF4AY } else{ onvertit a @@gonvertir E QPA B SA G WY ystemFoutFprint@gonvertir C 4 p orrespond X 4AY ystemFoutFprintln@rrondi@onvertitD PA C 4 gF4AY } GGyn invite l9utilisteur reommener ou quitter do{ ystemFoutFprintln@4ouhitezEvous onvertir une utre temprture c@yGxA4AY reponse a sFnextvine@AFhret@HAY }while@reponse 3a 9y9 88 reponse 3a 9x9AY }while@reponse aa 9y9AY ystemFoutFprintln@4eu revoir 34AY

58

CORRECTION

GGpin de progrmme } puli stti doule rrondi@doule eD int fA { return @douleA @ @intA @e B wthFpow@IHD fA C FSAA G wthFpow@IHD fAY }

Copier la correction Code web : 499371 

Expliquons un peu ce code


 Tout programme commence par une phase de dclaration des variables.  Nous achons le titre de notre programme.  Ensuite, vous voyez 2 do{ conscutifs correspondant deux conditions vrier :  la volont de l'utilisateur d'eectuer une nouvelle conversion ;  la vrication du mode de conversion.  Nous achons les renseignements l'cran, et rcuprons la temprature convertir pour la stocker dans une variable.  Selon le mode slectionn, on convertit la temprature et on ache le rsultat.  On invite l'utilisateur recommencer.  Fin du programme ! Ce programme n'est pas parfait, loin de l. La vocation de celui-ci tait de vous faire utiliser ce que vous avez appris, et je pense qu'il remplit bien sa fonction. J'espre que vous avez apprci ce TP. Je sais qu'il n'tait pas facile, mais avouez-le : il vous a bien fait utiliser tout ce que vous avez vu jusqu'ici !

59

CHAPITRE 6. TP : CONVERSION CELSIUS - FAHRENHEIT

60

Chapitre

7
Dicult :

Les tableaux

omme tout langage de programmation qui se respecte, Java travaille avec des tableaux. Vous verrez que ceux-ci s'avrent bien pratiques. . . Vous vous doutez (je suppose) que les tableaux dont nous parlons n'ont pas grand-chose voir avec ceux que vous connaissez ! En programmation, un tableau n'est rien d'autre qu'une variable un peu particulire. Nous allons en eet pouvoir lui aecter plusieurs valeurs ordonnes squentiellement que nous pourrons appeler au moyen d'un indice (ou d'un compteur, si vous prfrez). Il nous sura d'introduire l'emplacement du contenu dsir dans notre variable tableau pour la sortir, travailler avec, l'acher. . . Assez bavard : mettons-nous joyeusement au travail !

61

CHAPITRE 7. LES TABLEAUX

Tableau une dimension


Je viens de vous expliquer grosso modo ce qu'est un tableau en programmation. Si maintenant, je vous disais qu'il y a autant de types de tableaux que de types de variables ? Je crois voir quelques gouttes de sueur perler sur vos fronts. . . Pas de panique ! C'est trs logique : comme nous l'avons vu auparavant, une variable d'un type donn ne peut contenir que des lments de ce type : une variable de type int ne peut pas recevoir une chane de caractres. Il en va de mme pour les tableaux. Voyons tout de suite comment ils se dclarent :
<type du tableau> <nom du tableau> [] = { <contenu du tableau>};

La dclaration ressemble beaucoup celle d'une variable quelconque, si ce n'est la prsence de crochets [] aprs le nom de notre tableau et d'accolades {} encadrant l'initialisation de celui-ci. Dans la pratique, a nous donnerait quelque chose comme ceci :
int tleuintier a {HDIDPDQDRDSDTDUDVDW}Y doule tleuhoule a {HFHDIFHDPFHDQFHDRFHDSFHDTFHDUFHDVFHDWFH}Y hr tleugrtere a {99D99D99D9d9D9e9D9f9D9g9}Y tring tleughine a {4hineI4D 4hineP4D 4hineQ4 D 4hineR4}Y

Vous remarquez bien que la dclaration et l'initialisation d'un tableau se font comme avec une variable ordinaire : il faut utiliser des ' ' pour initialiser un tableau de caractres, des " " pour initialiser un tableau de String, etc. Vous pouvez aussi dclarer un tableau vide, mais celui-ci devra imprativement contenir un nombre de cases bien dni. Par exemple, si vous voulez un tableau vide de six entiers :
int tleuintier a new intTY GGyu enore int tleuintierP a new intTY

Cette opration est trs simple, car vraiment ressemblante ce que vous faisiez avec vos variables ; je vous propose donc tout de suite de nous pencher sur une belle variante de ces tableaux. . .

Les tableaux multidimensionnels


Ici, les choses se compliquent un peu, car un tableau multidimensionnel n'est rien d'autre qu'un tableau contenant au minimum deux tableaux. . . Je me doute bien que cette notion doit en erayer plus d'un, mais en ralit, elle n'est pas si dicile que a apprhender. Comme tout ce que je vous apprends en gnral ! Je ne vais pas vous faire de grand laus sur ce type de tableau, puisque je pense sincrement qu'un exemple vous en fera beaucoup mieux comprendre le concept. Imaginez un tableau avec deux lignes : la premire contiendra les premiers nombres pairs, et le deuxime contiendra les premiers nombres impairs. 62

UTILISER ET RECHERCHER DANS UN TABLEAU Ce tableau s'appellera premiersNombres. Voil ce que cela donnerait :
int premiersxomres a { {HDPDRDTDV}D{IDQDSDUDW} }Y

Nous voyons bien ici les deux lignes de notre tableau symbolises par les doubles crochets [][]. Et comme je l'ai dit plus haut, ce genre de tableau est compos de plusieurs tableaux. Ainsi, pour passer d'une ligne l'autre, nous jouerons avec la valeur du premier crochet. Exemple : premiersNombres[0][0] correspondra au premier lment de la ligne paire, et premiersNombres[1][0] correspondra au premier lment de la ligne impaire. Voici un petit schma en guise de synthse (gure 7.1).

Figure

7.1  Comprendre un tableau bidimensionnel

Maintenant, je vais vous proposer de vous amuser un peu avec les tableaux. . .

Utiliser et rechercher dans un tableau


Avant d'attaquer, je dois vous dire quelque chose de primordial : un tableau dbute toujours l'indice 0 ! Je m'explique : prenons l'exemple du tableau de caractres contenant les lettres de l'alphabet dans l'ordre qui a t donn plus haut. Si vous voulez acher la lettre  a  l'cran, vous devrez taper cette ligne de code :
ystemFoutFprintln@tleugrtereHAY

Cela implique qu'un tableau contenant 4 lments aura comme indices possibles 0, 1, 2 ou 3. Le 0 correspond au premier lment, le 1 correspond au 2e lment, le 2 correspond au 3e lment et le 3 correspond au 4e lment.

Une trs grande partie des erreurs sur les tableaux sont souvent dues un mauvais indice dans celui-ci. Donc prenez garde. . .
Ce que je vous propose, c'est tout simplement d'acher un des tableaux prsents ci-dessus dans son intgralit. Sachez qu'il existe une instruction qui retourne la taille d'un tableau : grce elle, nous pourrons arrter notre boucle (car oui, nous allons utiliser une boucle). Il s'agit de l'instruction <mon tableau>.length. Notre boucle for pourrait donc ressembler ceci : 63

CHAPITRE 7. LES TABLEAUX


hr tleugrtere a {99D99D99D9d9D9e9D9f9D9g9}Y for@int i a HY i ` tleugrtereFlengthY iCCA { ystemFoutFprintln@4e l9emplement 4 C i C4 du tleu nous vons a 4 C tleugrtereiAY }

Cela achera :
A A A A A A A l'emplacement l'emplacement l'emplacement l'emplacement l'emplacement l'emplacement l'emplacement 0 1 2 3 4 5 6 du du du du du du du tableau tableau tableau tableau tableau tableau tableau nous nous nous nous nous nous nous avons avons avons avons avons avons avons = = = = = = = a b c d e f g

Maintenant, nous allons essayer de faire une recherche dans un de ces tableaux. En gros, il va falloir eectuer une saisie clavier et regarder si celle-ci est prsente dans le tableau. . . Gardez la partie de code permettant de faire plusieurs fois la mme action ; ensuite, faites une boucle de recherche incluant la saisie clavier, un message si la saisie est trouve dans le tableau, et un autre message si celle-ci n'est pas trouve. Ce qui nous donne :
hr tleugrtere a {99D 99D 99D 9d9D 9e9D 9f9D 9g9}Y int i a HD emplement a HY hr reponse a 9 9Dr a 9 9Y nner s a new nner@ystemFinAY do {GGfoule priniple do {GGyn rpte ette oule tnt que l9utilisteur n9 ps rentr une lettre figurnt dns le tleu i a HY ystemFoutFprintln@4entrez une lettre en minusuleD 4AY r a sFnextvine@AFhret@HAY GGfoule de reherhe dns le tleu while@i ` tleugrtereFlength 88 r 3a tleugrtereiA iCCY GGi i ` U 9est que l oule n9 ps dpss le nomre de ses du tleu if @i ` tleugrtereFlengthA ystemFoutFprintln@4 v lettre 4 CrC 4 se trouve ien dns le tleu 34AY else GGinon ystemFoutFprintln@4 v lettre 4 CrC 4 ne se trouve ps dns le tleu 34AY

64

UTILISER ET RECHERCHER DANS UN TABLEAU


}while@i ba tleugrtereFlengthAY GGnt que l lettre de l9utilisteur GGne orrespond ps une lettre du tleu do{ ystemFoutFprintln@4oulezEvous essyer nouveu c @yGxA4AY reponse a sFnextvine@AFhret@HAY }while@reponse 3a 9x9 88 reponse 3a 9y9AY }while @reponse aa 9y9AY ystemFoutFprintln@4eu revoir 34AY

Le rsultat de ce code est sur la gure 7.2.

Figure

7.2  Rsultat de la recherche

Explicitons un peu ce code, et plus particulirement la recherche


Dans notre while, il y a deux conditions. La premire correspond au compteur : tant que celui-ci est infrieur ou gal au nombre d'lments du tableau, on l'incrmente pour regarder la valeur suivante. Nous passons ainsi en revue tout ce qui se trouve dans notre tableau. Si nous n'avions mis que cette condition, la boucle n'aurait fait que parcourir le tableau, sans voir si le caractre saisi correspond bien un caractre de notre tableau, d'o la deuxime condition. La deuxime correspond la comparaison entre le caractre saisi et la recherche dans le tableau. Grce elle, si le caractre saisi se trouve dans le tableau, la boucle prend n, et donc i a une valeur infrieure 7. ce stade, notre recherche est termine. Aprs cela, les conditions coulent de source ! Si nous avons trouv une correspondance entre le caractre saisi et notre tableau, i 65

CHAPITRE 7. LES TABLEAUX prendra une valeur infrieure 7 (vu qu'il y a 7 lments dans notre tableau, l'indice maximum tant 7-1, soit 6). Dans ce cas, nous achons un message conrmant la prsence de l'lment recherch. Dans le cas contraire, c'est l'instruction du else qui s'excutera.

Vous avez d remarquer la prsence d'un i = 0; dans une boucle. Ceci est primordial, sinon, lorsque vous reviendrez au dbut de celle-ci, i ne vaudra plus 0, mais la dernire valeur laquelle il aura t aect aprs les direntes incrmentations. Si vous faites une nouvelle recherche, vous commencerez par l'indice contenu dans i ; ce que vous ne voulez pas, puisque le but est de parcourir l'intgralit du tableau, donc depuis l'indice 0.
En travaillant avec les tableaux, vous serez confronts, un jour ou l'autre, au message suivant : java.lang.ArrayIndexOutOfBoundsException. Ceci signie qu'une erreur a t rencontre, car vous avez essay de lire (ou d'crire dans) une case qui n'a pas t dnie dans votre tableau ! Voici un exemple 1 :
tring str a new tringIHY GGv9instrution suivnte v dlenher une exeption GGr vous essyez d9rire l se II de votre tleu GGlors que eluiEi n9en ontient que IH @ ommene H 3A strIH a 4ne exeption4Y

Nous allons maintenant travailler sur le tableau bidimensionnel mentionn prcdemment. Le principe est vraiment identique celui d'un tableau simple, sauf qu'ici, il y a deux compteurs. Voici un exemple de code permettant d'acher les donnes par ligne, c'est--dire l'intgralit du sous-tableau de nombres pairs, puis le sous-tableau de nombres impairs :

Avec une boucle while


int premiersxomres a { {HDPDRDTDV}D{IDQDSDUDW} }D i a HD j a HY while @i ` PA { j a HY while@j ` SA { ystemFoutFprint@premiersxomresijAY jCCY } ystemFoutFprintln@44AY iCCY }

Et voil le rsultat (gure 7.3).


1. Nous verrons les exceptions lorsque nous aborderons la programmation oriente objet.

66

UTILISER ET RECHERCHER DANS UN TABLEAU

Figure

7.3  Achage du tableau

Dtaillons un peu ce code


 Dans un premier temps, on initialise les variables.  On entre ensuite dans la premire boucle (qui s'excutera deux fois, donc i vaut 0 la premire fois, et vaudra 1 pendant la deuxime), et on initialise j 0.  On entre ensuite dans la deuxime boucle, o j vaudra successivement 0, 1, 2, 3 et 4 pour acher le contenu du tableau d'indice 0 (notre premier i).  On sort de cette boucle ; notre i est ensuite incrment et passe 1.  On reprend le dbut de la premire boucle : initialisation de j 0.  On entre nouveau dans la deuxime boucle, o le processus est le mme que prcdemment (mais l, i vaut 1).  Enn, nous sortons des boucles et le programme termine son excution.

Le mme rsultat avec une boucle for


int premiersxomres a { {HDPDRDTDV}D{IDQDSDUDW} }Y for@int i a HY i ` PY iCCA { for@int j a HY j ` SY jCCA { ystemFoutFprint@premiersxomresijAY } ystemFoutFprintln@44AY }

Je vous avais parl d'une nouvelle syntaxe pour cette boucle, la voici :
tring t a {4toto4D 4titi4D 4tutu4D 4tete4D 4tt4}Y for@tring str X tA ystemFoutFprintln@strAY

Ceci signie qu' chaque tour de boucle, la valeur courante du tableau est mise dans la variable str. Vous constaterez que cette forme de boucle for est particulirement adapte aux parcours de tableaux ! Attention cependant, il faut imprativement que la variable passe en premier paramtre de la boucle for soit de mme type que la valeur de retour du tableau 2 .
2. Une variable de type String pour un tableau de String, un int pour un tableau d'int. . .

67

CHAPITRE 7. LES TABLEAUX Concernant les tableaux deux dimensions, que va retourner l'instruction de la premire boucle for ? Un tableau. Nous devrons donc faire une deuxime boucle an de parcourir ce dernier ! Voici un code qui permet d'acher un tableau deux dimensions de faon conventionnelle et selon la nouvelle version du JDK 1.5 3 :
tring ta{{4toto4D 4titi4D 4tutu4D 4tete4D 4tt4}D {4I4D 4P4D 4Q4D 4R4}}Y int i a HD j a HY for@tring sous X tA { i a HY for@tring str X sousA { ystemFoutFprintln@4v vleur de l nouvelle oule est X 4 C strAY ystemFoutFprintln@4v vleur du tleu l9indie 4CjC44CiC4 est X 4 C tjiAY iCCY } jCCY }

Je vous laisse le soin d'essayer ce code. Vous pourrez voir que nous rcuprons un tableau au cours de la premire boucle et parcourons ce mme tableau an de rcuprer les valeurs de celui-ci dans la deuxime. Simple, non ? En tout cas, je prfre nettement cette syntaxe ! Aprs, c'est vous de voir. . .

En rsum
 Un tableau est une variable contenant plusieurs donnes d'un mme type.  Pour dclarer un tableau, il faut ajouter des crochets [] la variable ou son type de dclaration.  Vous pouvez ajouter autant de dimensions votre tableau que vous le souhaitez, ceci en cumulant des crochets la dclaration.  Le premier lment d'un tableau est l'lment 0.  Vous pouvez utiliser la syntaxe du JDK 1.5 de la boucle for pour parcourir vos tableaux : for(String str : monTableauDeString).

3. Cette syntaxe ne fonctionnera pas sur les versions antrieures JDK 1.5.

68

Chapitre

8
Dicult :

Les mthodes de classe

aintenant que vous commencez crire de vrais programmes, vous vous rendez srement compte qu'il y a certaines choses que vous eectuez souvent. Plutt que de recopier sans arrt les mmes morceaux de code, vous pouvez crire une mthode. . . Ce chapitre aura pour but de vous faire dcouvrir la notion de mthode (on l'appelle  fonction  dans d'autres langages). Vous en avez peut-tre dj utilis une lors du premier TP, vous vous en souvenez ? Vous avez pu voir qu'au lieu de retaper le code permettant d'arrondir un nombre dcimal, vous pouviez l'inclure dans une mthode et appeler celle-ci. Le principal avantage des mthodes est de pouvoir factoriser le code : grce elles, vous n'avez qu'un seul endroit o eectuer des modications lorsqu'elles sont ncessaires. J'espre que vous comprenez mieux l'intrt de tout cela, car c'est ce que nous allons aborder ici. Cependant, ce chapitre ne serait pas drle si nous ne nous amusions pas crer une ou deux mthodes pour le plaisir. . . Et l, vous aurez beaucoup de choses retenir !

69

CHAPITRE 8. LES MTHODES DE CLASSE

Quelques mthodes utiles


Vous l'aurez compris, il existe normment de mthodes dans le langage Java, prsentes dans des objets comme String : vous devrez les utiliser tout au long de cet ouvrage (et serez mme amens en modier le comportement). ce point du livre, vous pouvez catgoriser les mthodes en deux  familles  : les natives et les vtres.

Des mthodes concernant les chanes de caractres


toLowerCase()

Cette mthode permet de transformer tout caractre alphabtique en son quivalent minuscule. Elle n'a aucun eet sur les chires : ce ne sont pas des caractres alphabtiques. Vous pouvez donc l'utiliser sans problme sur une chane de caractres comportant des nombres. Elle s'emploie comme ceci :
tring hine a new tring@4gygy y vi wyxhi 34AD hineP a new tring@AY hineP a hineFtovowergse@AY GGhonne 4ouou tout le monde 34

toUpperCase()

Celle-l est simple, puisqu'il s'agit de l'oppos de la prcdente. Elle transforme donc une chane de caractres en capitales, et s'utilise comme suit :
tring hine a new tring@4ouou ouou4AD hineP a new tring@AY hineP a hineFtoppergse@AY GGhonne 4gygy gygy4

length()

Celle-ci renvoie la longueur d'une chane de caractres (en comptant les espaces).
tring hine a new tring@4ouou 3 4AY int longueur a HY longueur a hineFlength@AY GGenvoie W

equals() Cette mthode permet de vrier (donc de tester) si deux chanes de ca-

ractres sont identiques. C'est avec cette fonction que vous eectuerez vos tests de condition sur les String. Exemple concret :
tring strI a new tring@4ouou4AD strP a new tring@4toutou4AY if @strIFequls@strPAA ystemFoutFprintln@4ves deux hnes sont identiques 34AY else ystemFoutFprintln@4ves deux hnes sont diffrentes 34AY

Vous pouvez aussi demander la vrication de l'ingalit grce l'oprateur de ngation. . . Vous vous en souvenez ? Il s'agit de  ! . Cela nous donne : 70

QUELQUES MTHODES UTILES


tring strI a new tring@4ouou4AD strP a new tring@4toutou4AY if @3strIFequls@strPAA ystemFoutFprintln@4ves deux hnes sont diffrentes 34AY else ystemFoutFprintln@4ves deux hnes sont identiques 34AY

Ce genre de condition fonctionne de la mme faon pour les boucles. Dans l'absolu, cette fonction retourne un boolen, c'est pour cette raison que nous pouvons y recourir dans les tests de condition.
charAt()

Le rsultat de cette mthode sera un caractre : il s'agit d'une mthode d'extraction de caractre. Elle ne peut s'oprer que sur des String ! Par ailleurs, elle prsente la mme particularit que les tableaux, c'est--dire que, pour cette mthode, le premier caractre sera le numro 0. Cette mthode prend un entier comme argument.
tring nre a new tring@4IPQRSTU4AY hr r a nreFhret@RAY GGenverr ii le rtre S

substring()

Cette mthode extrait une partie d'une chane de caractres. Elle prend deux entiers en arguments : le premier dnit le premier caractre (inclus) de la sous-chane extraire, le second correspond au dernier caractre (exclu) extraire. L encore, le premier caractre porte le numro 0.
tring hine a new tring@4l pix nihe4AD hineP a new tring@AY hineP a hineFsustring@QDIQAY GGermet d9extrire 4pix nihe4

indexOf()  lastIndexOf() indexOf() explore une chane de caractres la recherche d'une suite donne de ca-

ractres, et renvoie la position (ou l'index) de la sous-chane passe en argument. indexOf() explore partir du dbut de la chane, lastIndexOf() explore en partant de la n, mais renvoie l'index partir du dbut de la chane. Ces deux mthodes prennent un caractre ou une chane de caractres comme argument, et renvoient un int. Tout comme charAt() et substring(), le premier caractre porte le numro 0. Je crois qu'ici, un exemple s'impose, plus encore que pour les autres fonctions :
tring mot a new tring@4ntionstitutionnellement4AY int n a HY n n n n n a a a a a motFindexyf@9t9AY motFlstsndexyf@9t9AY motFindexyf@4ti4AY motFlstsndexyf@4ti4AY motFindexyf@9x9AY GGn GGn GGn GGn GGn vut vut vut vut vut P PR P IP EI

71

CHAPITRE 8. LES MTHODES DE CLASSE

Des mthodes concernant les mathmatiques


Les mthodes listes ci-dessous ncessitent la classe Math, prsente dans java.lang. Elle fait donc partie des fondements du langage. Par consquent, aucun import particulier n'est ncessaire pour utiliser la classe Math qui regorge de mthodes utiles :
doule a HFHY a wthFrndom@AY GGetourne un nomre ltoire GGompris entre H et ID omme HFHHHIQVSURTQPWQUIHSV doule sin a wthFsin@IPHAY GGv fontion sinus doule os a wthFos@IPHAY GGv fontion osinus doule tn a wthFtn@IPHAY GGv fontion tngente doule s a wthFs@EIPHFPSAY GGv fontion vleur solue @retourne le nomre sns le signeA doule d a PY doule exp a wthFpow@dD PAY GGv fontion exposnt GGsiD on initilise l vrile exp ve l vleur de d leve u rr GGv mthode pow@A prend don une vleur en premier prmtreD GGet un exposnt en seond

Ces mthodes retournent toutes un nombre de type double. Je ne vais pas vous faire un rcapitulatif de toutes les mthodes prsentes dans Java, sinon j'y serai encore dans mille ans. . . Toutes ces mthodes sont trs utiles, croyezmoi. Cependant, les plus utiles sont encore celles que nous crivons nous-mmes ! C'est tellement mieux quand cela vient de nous. . .

Crer sa propre mthode


Voici un exemple de mthode que vous pouvez crire :
puli stti doule rrondi@doule eD int fA { return @douleA @ @intA @e B wthFpow@IHD fA C FSAA G wthFpow@IHD fAY }

Dcortiquons un peu cela


 Tout d'abord, il y a le mot cl public. C'est ce qui dnit la porte de la mthode, nous y reviendrons lorsque nous programmerons des objets.  Ensuite, il y a static. Nous y reviendrons aussi.  Juste aprs, nous voyons double. Il s'agit du type de retour de la mthode. Pour faire simple, ici, notre mthode va renvoyer un double !  Vient ensuite le nom de la mthode. C'est avec ce nom que nous l'appellerons.  Puis arrivent les arguments de la mthode. Ce sont en fait les paramtres dont la mthode a besoin pour travailler. Ici, nous demandons d'arrondir le double A avec B chires derrire la virgule. 72

CRER SA PROPRE MTHODE  Finalement, vous pouvez voir une instruction return l'intrieur de la mthode. C'est elle qui eectue le renvoi de la valeur, ici un double. Nous verrons dans ce chapitre les dirents types de renvoi ainsi que les paramtres que peut accepter une mthode. Vous devez savoir deux choses concernant les mthodes :  elles ne sont pas limites en nombre de paramtres ;  il en existe trois grands types :  les mthodes qui ne renvoient rien. Les mthodes de ce type n'ont pas d'instruction return, et elles sont de type void ;  les mthodes qui retournent des types primitifs (double, int. . .). Elles sont de type double, int, char. . . Celles-ci possdent une instruction return ;  les mthodes qui retournent des objets. Par exemple, une mthode qui retourne un objet de type String. Celles-ci aussi comportent une instruction return. Jusque-l, nous n'avons crit que des programmes comportant une seule classe, ne disposant elle-mme que d'une mthode : la mthode main. Le moment est donc venu de crer vos propres mthodes. Que vous ayez utilis ou non la mthode arrondi dans votre TP, vous avez d voir que celle-ci se place l'extrieur de la mthode main, mais tout de mme dans votre classe ! Pour rappel, jetez un il la capture d'cran du TP 1 sur la gure 8.1.

Figure

8.1  Emplacement des mthodes

Si vous placez une de vos mthodes l'intrieur de la mthode main ou l'extrieur de votre classe, le programme ne compilera pas.
Puisque nous venons d'tudier les tableaux, nous allons crer des mthodes pour eux. Vous devez certainement vous souvenir de la faon de parcourir un tableau. . . Et si 73

CHAPITRE 8. LES MTHODES DE CLASSE nous faisions une mthode qui permet d'acher le contenu d'un tableau sans que nous soyons obligs de retaper la portion de code contenant la boucle ? Je me doute que vous n'en voyez pas l'intrt maintenant, car exception faite des plus courageux d'entre vous, vous n'avez utilis qu'un ou deux tableaux dans votre main du chapitre prcdent. Si je vous demande de dclarer vingt-deux tableaux et que je vous dis :  Allez, bande de Zros ! Parcourez-moi tout a ! , vous n'allez tout de mme pas crire vingt-deux boucles for ! De toute faon, je vous l'interdis. Nous allons crire une mthode. Celle-ci va :  prendre un tableau en paramtre ;  parcourir le tableau notre place ;  eectuer tous les System.out.println() ncessaires ;  ne rien renvoyer. Avec ce que nous avons dni, nous savons que notre mthode sera de type void et qu'elle prendra un tableau en paramtre. Voici un exemple de code complet :
puli lss dzI { puli stti void min@tring rgsA { tring t a {4toto4D 4tt4D 4titi4D 4tete4}Y prourirleu@tAY } stti void prourirleu@tring tfisA { for@tring str X tfisA ystemFoutFprintln@strAY }

Je sais que cela vous trouble encore, mais sachez que les mthodes ajoutes dans la classe main doivent tre dclares static. Fin du mystre dans la partie sur la programmation oriente objet !
Bon. Vous voyez que la mthode parcourt le tableau pass en paramtre. Si vous crez plusieurs tableaux et appelez la mthode sur ces derniers, vous vous apercevrez que la mthode ache le contenu de chaque tableau ! Voici un exemple ayant le mme eet que la mthode parcourirTableau, la dirence que celle-ci retourne une valeur : ici, ce sera une chane de caractres.
puli lss dzI { puli stti void min@tring rgsA { tring t a {4toto4D 4tt4D 4titi4D 4tete4}Y

74

LA SURCHARGE DE MTHODE
prourirleu@tAY ystemFoutFprintln@totring@tAAY

stti void prourirleu@tring tA { for@tring str X tA ystemFoutFprintln@strAY } stti tring totring@tring tA { ystemFoutFprintln@4wthode totring@A 3nEEEEEEEEEE4AY tring retour a 44Y for@tring str X tA retour Ca str C 4n4Y } return retourY

Vous voyez que la deuxime mthode retourne une chane de caractres, que nous devons acher l'aide de l'instruction System.out.println(). Nous achons la valeur renvoye par la mthode toString(). La mthode parcourirTableau, quant elle, crit au fur et mesure le contenu du tableau dans la console. Notez que j'ai ajout une ligne d'criture dans la console au sein de la mthode toString(), an de vous montrer o elle tait appele. Il nous reste un point important aborder. Imaginez un instant que vous ayez plusieurs types d'lments parcourir : des tableaux une dimension, d'autres deux dimensions, et mme des objets comme des ArrayList (nous les verrons plus tard, ne vous inquitez pas). Sans aller aussi loin, vous n'allez pas donner un nom dirent la mthode parcourirTableau pour chaque type primitif ! Vous avez d remarquer que la mthode que nous avons cre ne prend qu'un tableau de String en paramtre. Pas un tableau d'int ou de long, par exemple. Si seulement nous pouvions utiliser la mme mthode pour dirents types de tableaux. . . C'est l qu'entre en jeu ce qu'on appelle la surcharge.

La surcharge de mthode
La surcharge de mthode consiste garder le nom d'une mthode (donc un type de traitement faire : pour nous, lister un tableau) et changer la liste ou le type de ses paramtres. Dans le cas qui nous intresse, nous voulons que notre mthode parcourirTableau 75

CHAPITRE 8. LES MTHODES DE CLASSE puisse parcourir n'importe quel type de tableau. Nous allons donc surcharger notre mthode an qu'elle puisse aussi travailler avec des int, comme le montre cet exemple :
stti void prourirleu@tring tA { for@tring str X tA ystemFoutFprintln@strAY } stti void prourirleu@int tA { for@int str X tA ystemFoutFprintln@strAY }

Avec ces mthodes, vous pourrez parcourir de la mme manire :  les tableaux d'entiers ;  les tableaux de chanes de caractres. Vous pouvez faire de mme avec les tableaux deux dimensions. Voici quoi pourrait ressembler le code d'une telle mthode (je ne rappelle pas le code des deux mthodes ci-dessus) :
stti void prourirleu@tring tA { for@tring tP X tA { for@tring str X tPA ystemFoutFprintln@strAY } }

La surcharge de mthode fonctionne galement en ajoutant des paramtres la mthode. Cette mthode est donc valide :
stti void prourirleu@tring tD int iA { for@tring tP X tA { for@tring str X tPA ystemFoutFprintln@strAY } }

En fait, c'est la JVM qui va se charger d'invoquer l'une ou l'autre mthode : vous pouvez donc crer des mthodes ayant le mme nom, mais avec des paramtres dirents, en nombre ou en type. La machine virtuelle fait le reste. Ainsi, si vous avez bien dni toutes les mthodes ci-dessus, ce code fonctionne : 76

LA SURCHARGE DE MTHODE
tring ttr a {4toto4D 4titi4D 4tt4}Y int tsnt a {ID PD QD R}Y tring ttrP a {{4I4D 4P4D 4Q4D 4R4}D {4toto4D 4titi4D 4tt4}}Y GGv mthode ve un tleu de tring ser invoque prourirleu@ttrAY GGv mthode ve un tleu d9int ser invoque prourirleu@tsntAY GGv mthode ve un tleu de tring deux dimensions ser invoque prourirleu@ttrPAY

Vous venez de crer une mthode qui vous permet de centraliser votre code an de ne pas avoir retaper sans arrt les mmes instructions. Dans la partie suivante, vous apprendrez crer vos propres objets. Elle sera trs riche en informations, mais ne vous inquitez pas : nous apprendrons tout partir de zro. ;-)

En rsum
 Une mthode est un morceau de code rutilisable qui eectue une action bien dnie.  Les mthodes se dnissent dans une classe.  Les mthodes ne peuvent pas tre imbriques. Elles sont dclares les unes aprs les autres.  Une mthode peut tre surcharge en modiant le type de ses paramtres, leur nombre, ou les deux.  Pour Java, le fait de surcharger une mthode lui indique qu'il s'agit de deux, trois ou X mthodes direntes, car les paramtres d'appel sont dirents. Par consquent, Java ne se trompe jamais d'appel de mthode, puisqu'il se base sur les paramtres passs cette dernire.

77

CHAPITRE 8. LES MTHODES DE CLASSE

78

Deuxime partie
Java et la Programmation Oriente Objet

79

Chapitre

9
Dicult :

Votre premire classe

ans la premire partie de cet ouvrage sur la programmation en Java, nous avons travaill avec une seule classe. Vous allez apprendre qu'en faisant de la programmation oriente objet, nous travaillerons en fait avec de nombreuses classes. Rappelez-vous la premire partie : vous avez dj utilis des objets. . . Oui ! Lorsque vous faisiez ceci : String str = new String("tiens... un objet String"); Ici str est un objet String. Vous avez utilis un objet de la classe String : on dit que vous avez cr une instance de la classe String(). Le moment est venu pour vous de crer vos propres classes.

81

CHAPITRE 9. VOTRE PREMIRE CLASSE Commenons par une dnition. Une classe est une structure informatique reprsentant les principales caractristiques d'un lment du monde rel grce :  des variables, qui reprsentent les divers attributs de l'lment que vous souhaitez utiliser ;  des mthodes, qui permettent de dnir les comportements de vos lments. Une classe contient donc des variables et des mthodes, qui forment un tout. Voyons comment en crer une de toutes pices !

Structure de base
Une classe peut tre compare un moule qui, lorsque nous le remplissons, nous donne un objet ayant la forme du moule ainsi que toutes ses caractristiques. Comme quand vous tiez enfants, lorsque vous vous amusiez avec de la pte modeler. Si vous avez bien suivi la premire partie de ce livre, vous devriez savoir que notre classe contenant la mthode main ressemble ceci :
lss glssewin{ puli stti void min@tring rgsA{ GGos donnesD vrilesD diffrents tritementsFFF }GGpin de l mthode min }GGpin de votre lsse

Crez cette classe et cette mthode main (vous savez le faire, maintenant). Puisque nous allons faire de la POO 1 , nous allons crer une seconde classe dans ce fameux projet ! Crons sans plus tarder une classe Ville. Allez dans File/New/Class ou utilisez le raccourci dans la barre d'outils, comme sur la gure 9.1.

Figure

9.1  Nouvelle classe Java

Nommez votre classe : Ville 2 . Cette fois, vous ne devez pas y crer la mthode main.

Il ne peut y avoir qu'une seule mthode main active par projet ! Souvenezvous que celle-ci est le point de dpart de votre programme. Pour tre tout fait prcis, plusieurs mthodes main peuvent cohabiter dans votre projet, mais une seule sera considre comme le point de dpart de votre programme !
Au nal, vous devriez avoir le rendu de la gure 9.2.
1. Programmation Oriente Objet. 2. Avec un  V  : convention de nommage oblige !

82

LES CONSTRUCTEURS

Figure

9.2  Classe Ville

Ici, notre classe Ville est prcde du mot cl public. Vous devez savoir que lorsque nous crons une classe comme nous l'avons fait, Eclipse nous facilite la tche en ajoutant automatiquement ce mot cl, qui correspond la porte de la classe 3 . En programmation, la porte dtermine qui peut faire appel une classe, une mthode ou une variable. Vous avez dj rencontr la porte public : cela signie que tout le monde peut faire appel l'lment 4 . Nous allons ici utiliser une autre porte : private. Elle signie que notre mthode ne pourra tre appele que depuis l'intrieur de la classe dans laquelle elle se trouve ! Les mthodes dclares private correspondent souvent des mcanismes internes une classe que les dveloppeurs souhaitent  cacher  ou simplement ne pas rendre accessibles de l'extrieur de la classe. . .

Il en va de mme pour les variables. Nous allons voir que nous pouvons protger des variables grce au mot cl private. Le principe sera le mme que pour les mthodes. Ces variables ne seront alors accessibles que dans la classe o elles seront nes. . .
Bon. Toutes les conditions sont runies pour commencer activement la programmation oriente objet ! Et si nous allions crer notre premire ville ?

Les constructeurs
Vu que notre objectif dans ce chapitre est de construire un objet Ville, il va falloir dnir les donnes qu'on va lui attribuer. Nous dirons qu'un objet Ville possde :  un nom, sous la forme d'une chane de caractres ;  un nombre d'habitants, sous la forme d'un entier ;  un pays apparent, sous la forme d'une chane de caractres. Nous allons faire ceci en mettant des variables d'instance 5 dans notre classe. Celleci va contenir une variable dont le rle sera de stocker le nom, une autre stockera le
3. Retenez pour l'instant que public class UneClasse{} et class UneClasse{} sont presque quivalents ! 4. Ici dans le cas qui nous intresse il s'agit d'une mthode. Une mthode marque comme public peut donc tre appele depuis n'importe quel endroit du programme. 5. Ce sont de simples variables identiques celles que vous manipulez habituellement.

83

CHAPITRE 9. VOTRE PREMIRE CLASSE nombre d'habitants et la dernire se chargera du pays ! Voici quoi ressemble notre classe Ville prsent :
puli lss ille{ tring nomilleY tring nomysY int nreritntsY }

Contrairement aux classes, les variables d'instance prsentes dans une classe sont public si vous ne leur spciez pas de porte. Alors, on parle de variable d'instance, parce que dans nos futures classes Java qui dniront des objets, il y aura plusieurs types de variables (nous approfondirons ceci dans ce chapitre). Pour le moment, sachez qu'il y a trois grands types de variables dans une classe objet.  Les variables d'instance : ce sont elles qui dniront les caractristiques de notre objet.  Les variables de classe : celles-ci sont communes toutes les instances de votre classe.  Les variables locales : ce sont des variables que nous utiliserons pour travailler dans notre objet. Dans l'immdiat, nous allons travailler avec des variables d'instance an de crer des objets dirents. Il ne nous reste plus qu' crer notre premier objet, pour ce faire, nous allons devoir utiliser ce qu'on appelle des constructeurs. Un constructeur est une mthode d'instance qui va se charger de crer un objet et, le cas chant, d'initialiser ses variables de classe ! Cette mthode a pour rle de signaler la JVM 6 qu'il faut rserver de la mmoire pour notre futur objet et donc, par extension, d'en rserver pour toutes ses variables. Notre premier constructeur sera ce qu'on appelle communment un constructeur par dfaut, c'est--dire qu'il ne prendra aucun paramtre, mais permettra tout de mme d'instancier un objet, et vu que nous sommes perfectionnistes, nous allons y initialiser nos variables d'instance. Voici votre premier constructeur :
puli lss ille{ GGtoke le nom de notre ville tring nomilleY GGtoke le nom du pys de notre ville tring nomysY GGtoke le nomre d9hitnts de notre ville int nreritntsY GGgonstruteur pr dfut puli ille@A{ ystemFoutFprintln@4grtion d9une ville 34AY nomille a 4snonnu4Y nomys a 4snonnu4Y
6. Java Virtual Machine.

84

LES CONSTRUCTEURS
nreritnts a HY

Vous avez remarqu que le constructeur est en fait une mthode qui n'a aucun type de retour (void, double. . .) et qui porte le mme nom que notre classe ! Ceci est une rgle immuable : le (les) constructeur(s) d'une classe doit (doivent) porter le

mme nom que la classe !

Son corollaire est qu'un objet peut avoir plusieurs constructeurs. Il s'agit de la mme mthode, mais surcharge ! Dans notre premier constructeur, nous n'avons pass aucun paramtre, mais nous allons bientt en mettre. Vous pouvez d'ores et dj crer une instance de Ville. Cependant, commencez par vous rappeler qu'une instance d'objet se fait grce au mot cl new, comme lorsque vous crez une variable de type String. Maintenant, vu que nous allons crer des objets Ville, nous allons procder comme avec les String. Vrions que l'instanciation s'effectue comme il faut. Allons dans notre classe contenant la mthode main et instancions un objet Ville. Je suppose que vous avez devin que le type de notre objet sera Ville !
puli lss dzI{ puli stti void min@tring rgsA{ ille ville a new ille@AY } }

Excutez ce code, vous devriez avoir l'quivalent de la gure 9.3 sous les yeux.

Figure

9.3  Cration d'un objet Ville

Maintenant, nous devons mettre des donnes dans notre objet, ceci an de pouvoir commencer travailler. . . Le but sera de parvenir une dclaration d'objet se faisant comme ceci : 85

CHAPITRE 9. VOTRE PREMIRE CLASSE


ille villeI a new ille@4wrseille4D IPQRSTUVWD 4prne4AY

Vous avez remarqu qu'ici, les paramtres sont renseigns : eh bien il sut de crer une mthode qui rcupre ces paramtres et initialise les variables de notre objet, ce qui achvera notre constructeur d'initialisation. Voici le constructeur de notre objet Ville, celui qui permet d'avoir des objets avec des paramtres dirents :
puli lss ille { GGtoke le nom de notre ville tring nomilleY GGtoke le nom du pys de notre ville tring nomysY GGtoke le nomre d9hitnts de notre ville int nreritntsY GGgonstruteur pr dfut puli ille@A{ ystemFoutFprintln@4grtion d9une ville 34AY nomille a 4snonnu4Y nomys a 4snonnu4Y nreritnts a HY } GGgonstruteur ve prmtres GGt9i jout un  p en premire lettre des prmtresF GGge n9est ps une onventionD mis peut tre un on moyen de les reprerF puli ille@tring pxomD int pxreD tring pysA { ystemFoutFprintln@4grtion d9une ville ve des prmtres 34AY nomille a pxomY nomys a pysY nreritnts a pxreY }

Copier ce code Code web : 215266  Dans ce cas, l'exemple de dclaration et d'initialisation d'un objet Ville que je vous ai montr un peu plus haut fonctionne sans aucun souci ! Mais il vous faudra respecter scrupuleusement l'ordre des paramtres passs lors de l'initialisation de votre objet : sinon, c'est l'erreur de compilation coup sr ! Ainsi :
GGv9ordre est respet uun soui ille villeI a new ille@4wrseille4D IPQRSTUVWD 4prne4AY GGirreur dns l9ordre des prmtres erreur de ompiltion u finl ille villeP a new ille@IPRSTD 4prne4D 4ville4AY

86

LES CONSTRUCTEURS Par contre, notre objet prsente un gros dfaut : les variables d'instance qui le caractrisent sont accessibles dans votre classe contenant votre main ! Ceci implique que vous pouvez directement modier les attributs de la classe. Testez ce code et vous verrez que le rsultat est identique la gure 9.4 :
puli lss dzI { puli stti void min@tring rgsA { ille ville a new ille@AY ystemFoutFprintln@villeFnomilleAY villeFnomille a 4l tte toto 3 3 3 34Y ystemFoutFprintln@villeFnomilleAY ille villeP a new ille@4wrseille4D IPQRSTUVWD 4prne4AY villePFnomys a 4v tte tutu 3 3 3 3 4Y ystemFoutFprintln@villePFnomysAY

} }

Figure

9.4  Modication des donnes de notre objet

Vous constatez que nous pouvons accder aux variables d'instance en utilisant le  . , comme lorsque vous appelez la mthode subString() de l'objet String. C'est trs risqu, et la plupart des programmeurs Java vous le diront. Dans la majorit des cas, nous allons contrler les modications des variables de classe, de manire ce qu'un code extrieur ne fasse pas n'importe quoi avec nos objets ! En plus de a, imaginez que vous souhaitiez faire quelque chose chaque fois qu'une valeur change ; si vous ne protgez pas vos donnes, ce sera impossible raliser. . . C'est pour cela que nous protgeons nos variables d'instance en les dclarant private, comme ceci :
puli lss ille { privte tring nomilleY privte tring nomysY privte int nreritntsY

87

CHAPITRE 9. VOTRE PREMIRE CLASSE


GG FFF

Dsormais, ces attributs ne sont plus accessibles en dehors de la classe o ils sont dclars ! Nous allons maintenant voir comment accder tout de mme nos donnes.

Accesseurs et mutateurs
Un accesseur est une mthode qui va nous permettre d'accder aux variables de nos objets en lecture, et un mutateur nous permettra d'en faire de mme en criture ! Grce aux accesseurs, vous pourrez acher les variables de vos objets, et grce aux mutateurs, vous pourrez les modier :
puli lss ille { GGves vriles et les onstruteurs n9ont ps hngFFF GGBBBBBBBBBBBBB eggii BBBBBBBBBBBBB

GGetourne le nom de l ville puli tring getxom@A { return nomilleY } GGetourne le nom du pys puli tring getxomys@A { return nomysY } GG etourne le nomre d9hitnts puli int getxomreritnts@A { return nreritntsY } GGBBBBBBBBBBBBB wei BBBBBBBBBBBBB GGhfinit le nom de l ville puli void setxom@tring pxomA { nomille a pxomY } GGhfinit le nom du pys puli void setxomys@tring pysA { nomys a pysY } GGhfinit le nomre d9hitnts puli void setxomreritnts@int nreA {

88

ACCESSEURS ET MUTATEURS
nreritnts a nreY

} }

Nos accesseurs sont bien des mthodes, et elles sont public pour que vous puissiez y accder depuis une autre classe que celle-ci : depuis le main, par exemple. Les accesseurs sont du mme type que la variable qu'ils doivent retourner. Les mutateurs sont, par contre, de type void. Ce mot cl signie  rien  ; en eet, ces mthodes ne retournent aucune valeur, elles se contentent de les mettre jour.

Je vous ai fait faire la dirence entre accesseurs et mutateurs, mais gnralement, lorsqu'on parle d'accesseurs, ce terme inclut galement les mutateurs. Autre chose : il s'agit ici d'une question de convention de nommage. Les accesseurs commencent par get et les mutateurs par set, comme vous pouvez le voir ici. On parle d'ailleurs parfois de Getters et de Setters.
prsent, essayez ce code dans votre mthode main :
ille v a new ille@AY ille vI a new ille@4wrseille4D IPQRSTD 4prne4AY ille vP a new ille@4io4D QPITSRD 4frsil4AY ystemFoutFprintln@4n v a 4CvFgetxom@AC4 ville de 4CvFgetxomreritnts@AC 4 hitnts se situnt en 4CvFgetxomys@AAY ystemFoutFprintln@4 vI a 4CvIFgetxom@AC4 ville de 4CvIFgetxomreritnts@AC 4 hitnts se situnt en 4CvIFgetxomys@AAY ystemFoutFprintln@4 vP a 4CvPFgetxom@AC4 ville de 4CvPFgetxomreritnts@AC 4 hitnts se situnt en 4CvPFgetxomys@AC4nn4AY GB xous llons interhnger les illes vI et vP tout pr l9intermdiire d9un utre ojet illeF

BG ille temp a new ille@AY temp a vIY vI a vPY vP a tempY

ystemFoutFprintln@4 vI a 4CvIFgetxom@AC4 ville de 4CvIFgetxomreritnts@AC 4 hitnts se situnt en 4CvIFgetxomys@AAY ystemFoutFprintln@4 vP a 4CvPFgetxom@AC4 ville de 4CvPFgetxomreritnts@AC 4 hitnts se situnt en 4CvPFgetxomys@AC4nn4AY GB xous llons mintennt interhnger leurs noms ette fois pr le iis de leur esseursF BG vIFsetxom@4rong uong4AY

89

CHAPITRE 9. VOTRE PREMIRE CLASSE


vPFsetxom@4hjiouti4AY ystemFoutFprintln@4 vI a 4CvIFgetxom@AC4 4CvIFgetxomreritnts@AC 4 hitnts ystemFoutFprintln@4 vP a 4CvPFgetxom@AC4 4CvPFgetxomreritnts@AC 4 hitnts 4CvPFgetxomys@AC4nn4AY ville de se situnt en 4CvIFgetxomys@AAY ville de se situnt en

la compilation, vous devriez obtenir la gure 9.5.

Figure

9.5  Essai des accesseurs

Vous voyez bien que les constructeurs ont fonctionn, que les accesseurs tournent merveille et que vous pouvez commencer travailler avec vos objets Ville. Par contre, pour acher le contenu, on pourrait faire plus simple, comme par exemple crer une mthode qui se chargerait de faire tout ceci. . . Je sais ce que vous vous dites :  Mais les accesseurs, ce ne sont pas des mthodes ? . Bien sr que si, mais il vaut mieux bien distinguer les dirents types de mthodes dans un objet :  les constructeurs mthodes servant crer des objets ;  les accesseurs mthodes servant accder aux donnes des objets ;  les mthodes d'instance mthodes servant la gestion des objets. Avec nos objets Ville, notre choix est un peu limit par le nombre de mthodes possibles, mais nous pouvons tout de mme en faire une ou deux pour l'exemple :  faire un systme de catgories de villes par rapport leur nombre d'habitants ( <1000 A, <10 000 B. . .). Ceci est dtermin la construction ou la rednition du nombre d'habitants : ajoutons donc une variable d'instance de type char notre classe et appelons-la categorie. Pensez ajouter le traitement aux bons endroits ;  faire une mthode de description de notre objet Ville ;  une mthode pour comparer deux objets par rapport leur nombre d'habitants.

Nous voulons que la classe Ville gre la faon de dterminer la catgorie ellemme, et non que cette action puisse tre opre de l'extrieur. La mthode qui fera ceci sera donc dclare private.
90

ACCESSEURS ET MUTATEURS Par contre, un problme va se poser ! Vous savez dj qu'en Java, on appelle les mthodes d'un objet comme ceci : monString.subString(0,4);. Cependant, vu qu'il va falloir qu'on travaille depuis l'intrieur de notre objet, vous allez encore avoir un mot cl retenir. . . Cette fois, il s'agit du mot cl this. Voici tout d'abord le code de notre classe Ville en entier, c'est--dire comportant les mthodes dont on vient de parler :


La classe Ville Code web : 570853 

puli lss ille { privte privte privte privte tring nomilleY tring nomysY int nreritntsY hr tegorieY

puli ille@A{ ystemFoutFprintln@4grtion d9une ville 34AY nomille a 4snonnu4Y nomys a 4snonnu4Y nreritnts a HY thisFsetgtegorie@AY } puli ille@tring pxomD int pxreD tring pysA { ystemFoutFprintln@4grtion d9une ville ve des prmtres 34AY nomille a pxomY nomys a pysY nreritnts a pxreY thisFsetgtegorie@AY } GGetourne le nom de l ville puli tring getxom@A { return nomilleY } GGetourne le nom du pys puli tring getxomys@A { return nomysY } GG etourne le nomre d9hitnts puli int getxomreritnts@A { return nreritntsY } GGetourne l tgorie de l ville puli hr getgtegorie@A

91

CHAPITRE 9. VOTRE PREMIRE CLASSE


{ }

return tegorieY

GGhfinit le nom de l ville puli void setxom@tring pxomA { nomille a pxomY } GGhfinit le nom du pys puli void setxomys@tring pysA { nomys a pysY } GGhfinit le nomre d9hitnts puli void setxomreritnts@int nreA { nreritnts a nreY thisFsetgtegorie@AY } GGhfinit l tgorie de l ville privte void setgtegorie@A { int ornesuperieures a {HD IHHHD IHHHHD IHHHHHD SHHHHHD IHHHHHHD SHHHHHHD IHHHHHHH}Y hr tegories a {9c9D 9e9D 9f9D 9g9D 9h9D 9i9D 9p9D 9q9D 9r9}Y int i a HY while @i ` ornesuperieuresFlength 88 thisFnreritnts ba ornesuperieuresiA iCCY } thisFtegorie a tegoriesiY ville est une ville de 4CthisFnomysC X 4CthisFnreritntsC elle est don de tgorie X 4CthisFtegorieY

GGetourne l desription de l puli tring derisoi@A{ return 4t4CthisFnomilleC4 4D elle omporte 4 hitnt@sA ab }

GGetourne une hne de rtres selon le rsultt de l omprison puli tring omprer@ille vIA{ tring str a new tring@AY if @vIFgetxomreritnts@A b thisFnreritntsA str a vIFgetxom@AC4 est une ville plus peuple que 4CthisFnomilleY

92

ACCESSEURS ET MUTATEURS

else str a thisFnomilleC4 est une ville plus peuple que 4CvIFgetxom@AY } return strY

Pour simplier, this 7 fait rfrence l'objet courant !


Pour expliciter le fonctionnement du mot cl this, prenons l'exemple de la mthode comparer(Ville V1). La mthode va s'utiliser comme suit :
ille a new ille@4vyon4D TSRD 4prne4AY ille P a new ille@4ville4D IPQD 4prne4AY Fomprer@PAY

Dans cette mthode, nous voulons comparer le nombre d'habitants de chacun des deux objets Ville. Pour accder la variable nbreHabitants de l'objet V2, il sut d'utiliser la syntaxe V2.getNombreHabitants() ; nous ferons donc rfrence la proprit nbreHabitants de l'objet V2. Mais l'objet V, lui, est l'objet appelant de cette mthode. Pour se servir de ses propres variables, on utilise alors this.nbreHabitants, ce qui a pour eet de faire appel la variable nbreHabitants de l'objet excutant la mthode comparer(Ville V). Explicitons un peu les trois mthodes qui ont t dcrites prcdemment.

La mthode categorie()
Elle ne prend aucun paramtre, et ne renvoie rien : elle se contente de mettre la variable de classe categorie jour. Elle dtermine dans quelle tranche se trouve la ville grce au nombre d'habitants de l'objet appelant, obtenu au moyen du mot cl this. Selon le nombre d'habitants, le caractre renvoy changera. Nous l'appelons lorsque nous construisons un objet Ville (que ce soit avec ou sans paramtre), mais aussi lorsque nous rednissons le nombre d'habitants : de cette manire, la catgorie est automatiquement mise jour, sans qu'on ait besoin de faire appel la mthode.

La mthode decrisToi()
Celle-ci nous renvoie un objet de type String. Elle fait rfrence aux variables qui composent l'objet appelant la mthode, toujours grce this, et nous renvoie donc
7. Bien que la traduction anglaise exacte soit  ceci , il faut comprendre  moi . l'intrieur d'un objet, ce mot cl permet de dsigner une de ses variables ou une de ses mthodes.

93

CHAPITRE 9. VOTRE PREMIRE CLASSE une chane de caractres qui nous dcrit l'objet en numrant ses composants.

La mthode comparer(Ville V1)


Elle prend une ville en paramtre, pour pouvoir comparer les variables nbreHabitants de l'objet appelant la mthode et de celui pass en paramtre pour nous dire quelle ville est la plus peuple ! Et si nous faisions un petit test ?
ille v a new ille@AY ille vI a new ille@4wrseille4D IPQTD 4prne4AY ille vP a new ille@4io4D QPITSRD 4frsil4AY ystemFoutFprintln@4nn4CvIFderisoi@AAY ystemFoutFprintln@vFderisoi@AAY ystemFoutFprintln@vPFderisoi@AC4nn4AY ystemFoutFprintln@vIFomprer@vPAAY

Ce qui devrait donner le rsultat de la gure 9.6.

Figure

9.6  Test des mthodes

Je viens d'avoir une ide : et si nous essayions de savoir combien de villes nous avons cres ? Comment faire ? Avec une variable de classe !

Les variables de classes


Comme je vous le disais au dbut de ce chapitre, il y a plusieurs types de variables dans une classe. Nous avons vu les variables d'instance qui forment la carte d'identit d'un objet ; maintenant, voici les variables de classe. Celles-ci peuvent s'avrer trs utiles. Dans notre exemple, nous allons compter le nombre d'instances de notre classe Ville, mais nous pourrions les utiliser pour bien d'autres choses (un taux de TVA dans une classe qui calcule le prix TTC, par exemple). La particularit de ce type de variable, c'est qu'elles seront communes toutes les instances de la classe ! Crons sans plus attendre notre compteur d'instances. Il s'agira d'une variable de type int que nous appellerons nbreInstance, et qui sera public ; nous mettrons aussi son homologue en private en place et l'appellerons nbreInstanceBis (il sera ncessaire de mettre un accesseur en place pour cette variable). An qu'une variable soit une 94

LES VARIABLES DE CLASSES variable de classe, elle doit tre prcde du mot cl static. Cela donnerait dans notre classe Ville :
puli lss ille { GGriles puliques qui omptent les instnes puli stti int nresnstnes a HY GGrile prive qui ompter ussi les instnes privte stti int nresnstnesfis a HY GGves utres vriles n9ont ps hng puli ille@A{ GGyn inrmente nos vriles hque ppel ux onstruteurs nresnstnesCCY nresnstnesfisCCY GGve reste ne hnge psF } puli ille@tring pxomD int pxreD tring pysA { GGyn inrmente nos vriles hque ppel ux onstruteurs nresnstnesCCY nresnstnesfisCCY GGve reste ne hnge ps } puli stti int getxomresnstnesfis@A { return nresnstnesfisY } GGve reste du ode est le mme qu9vnt

Vous avez d remarquer que l'accesseur de notre variable de classe dclare prive est aussi dclar static : ceci est une rgle ! Toutes les mthodes de classe n'utilisant que des variables de classe doivent tre dclares static. On les appelle des mthodes de classe, car il n'y en a qu'une pour toutes vos instances. Par contre ce n'est plus une mthode de classe si celle-ci utilise des variables d'instance en plus de variables de classe. . . prsent, si vous testez le code suivant, vous allez constater l'utilit des variables de classe :
ille v a new ille@AY ystemFoutFprintln@4ve nomre d9instnes de l lsse ille est X 4 C illeFnresnstnesAY ystemFoutFprintln@4ve nomre d9instnes de l lsse ille est X 4 C illeFgetxomresnstnesfis@AAY ille vI a new ille@4wrseille4D IPQTD 4prne4AY

95

CHAPITRE 9. VOTRE PREMIRE CLASSE


ystemFoutFprintln@4ve nomre d9instnes de l lsse ille est X 4 C illeFnresnstnesAY ystemFoutFprintln@4ve nomre d9instnes de l lsse ille est X 4 C illeFgetxomresnstnesfis@AAY ille vP a new ille@4io4D QPITSRD 4frsil4AY ystemFoutFprintln@4ve nomre d9instnes de l lsse ille est X 4 C illeFnresnstnesAY ystemFoutFprintln@4ve nomre d9instnes de l lsse ille est X 4 C illeFgetxomresnstnesfis@AAY

Le rsultat en gure 9.7 montre que le nombre augmente chaque instanciation.

Figure

9.7  Utilisation de variables de classe

Lorsque vous avez vu les mthodes, vous les avez dclares public. Vous auriez galement pu les dclarer private, mais attention, dans les deux cas, il faut aussi qu'elles soient static, car elles sont excutes dans un contexte static : la mthode main.

Le principe d'encapsulation
Voil, vous venez de construire votre premier objet  maison . Cependant, sans le savoir, vous avez fait plus que a : vous avez cr un objet dont les variables sont protges de l'extrieur. En eet, depuis l'extrieur de la classe, elles ne sont accessibles que via les accesseurs et mutateurs que nous avons dni. C'est le principe d'encapsulation ! En fait, lorsqu'on procde de la sorte, on s'assure que le fonctionnement interne l'objet est intgre, car toute modication d'une donne de l'objet est matrise. Nous avons dvelopp des mthodes qui s'assurent qu'on ne modie pas n'importe comment les variables. Prenons l'exemple de la variable nbreHabitants. L'encapsuler nous permet, lors de son aectation, de dduire automatiquement la catgorie de l'objet Ville, chose qui n'est pas facilement faisable sans encapsulation. Par extension, si vous avez besoin d'eectuer des oprations dtermines lors de l'aectation du nom d'une ville par exemple, vous n'aurez pas passer en revue tous les codes source utilisant l'objet Ville : vous n'aurez qu' modier l'objet (ou la mthode) en question, et le tour sera jou. Si vous vous demandez l'utilit de tout cela, dites-vous que vous ne serez peut-tre pas seuls dvelopper vos logiciels, et que les personnes utilisant vos classes n'ont pas 96

LE PRINCIPE D'ENCAPSULATION savoir ce qu'il s'y passe : seules les fonctionnalits qui leurs sont oertes comptent. Vous le verrez en continuant la lecture de cet ouvrage, Java est souple parce qu'il ore beaucoup de fonctionnalits pouvant tre retravailles selon les besoins, mais gardez l'esprit que certaines choses vous seront volontairement inaccessibles, pour viter que vous ne  cassiez  quelque chose.

En rsum
 Une classe permet de dnir des objets. Ceux-ci ont des attributs (variables d'instance) et des mthodes (mthodes d'instance + accesseurs).  Les objets permettent d'encapsuler du code et des donnes.  Le ou les constructeurs d'une classe doivent porter le mme nom que la classe et n'ont pas de type de retour.  L'ordre des paramtres passs dans le constructeur doit tre respect.  Il est recommand de dclarer ses variables d'instance private, pour les protger d'une mauvaise utilisation par le programmeur.  On cre des accesseurs et mutateurs (mthodes getters et setters) pour permettre une modication sre des variables d'instance.  Dans une classe, on accde aux variables de celle-ci grce au mot cl this.  Une variable de classe est une variable devant tre dclare static.  Les mthodes n'utilisant que des variables de classe doivent elles aussi tre dclares static.  On instancie un nouvel objet grce au mot cl new.

97

CHAPITRE 9. VOTRE PREMIRE CLASSE

98

Chapitre

10
Dicult :

L'hritage

e vous arrte tout de suite, vous ne toucherez rien. Pas de rapport d'argent entre nous. . . :-) Non, la notion d'hritage en programmation est dirente de celle que vous connaissez, bien qu'elle en soit tout de mme proche. C'est l'un des fondements de la programmation oriente objet ! Imaginons que, dans le programme ralis prcdemment, nous voulions crer un autre type d'objet : des objets Capitale. Ceux-ci ne seront rien d'autre que des objets Ville avec un paramtre en plus. . . disons un monument. Vous n'allez tout de mme pas recoder tout le contenu de la classe Ville dans la nouvelle classe ! Dj, ce serait vraiment contraignant, mais en plus, si vous aviez modier le fonctionnement de la catgorisation de nos objets Ville, vous auriez aussi eectuer la modication dans la nouvelle classe. . . Ce n'est pas terrible. Heureusement, l'hritage permet des objets de fonctionner de la mme faon que d'autres.

99

CHAPITRE 10. L'HRITAGE

Le principe de l'hritage
Comme je vous l'ai dit dans l'introduction, la notion d'hritage est l'un des fondements de la programmation oriente objet. Grce elle, nous pourrons crer des classes hrites 1 de nos classes mres 2 . Nous pourrons crer autant de classes drives, par rapport notre classe de base, que nous le souhaitons. De plus, nous pourrons nous servir d'une classe drive comme d'une classe de base pour laborer encore une autre classe drive. Reprenons l'exemple dont je vous parlais dans l'introduction. Nous allons crer une nouvelle classe, nomme Capitale, hrite de Ville. Vous vous rendrez vite compte que les objets Capitale auront tous les attributs et toutes les mthodes associs aux objets Ville !
lss gpitle extends ille { }

C'est le mot cl extends qui informe Java que la classe Capitale est hrite de Ville. Pour vous le prouver, essayez ce morceau de code dans votre main :
gpitle p a new gpitle@AY ystemFoutFprintln@pFderisoi@AAY

Vous devriez avoir la gure 10.1 en guise de rendu.

Figure

10.1  Objet Capitale

C'est bien la preuve que notre objet Capitale possde les proprits de notre objet Ville. Les objets hrits peuvent accder toutes les mthodes public 3 de leur classe mre, dont la mthode decrisToi() dans le cas qui nous occupe. En fait, lorsque vous dclarez une classe, si vous ne spciez pas de constructeur, le compilateur 4 crera, au moment de l'interprtation, le constructeur par dfaut. En revanche, ds que vous avez cr un constructeur, n'importe lequel, la JVM ne cre plus le constructeur par dfaut. Notre classe Capitale hrite de la classe Ville, par consquent, le constructeur de notre objet appelle, de faon tacite, le constructeur de la classe mre. C'est pour cela que les variables d'instance ont pu tre initialises ! Par contre, essayez ceci dans votre classe :
1. 2. 3. 4. Les classes hrites sont aussi appeles classes drives. Les classes mres sont aussi appeles classes de base. Ce n'est pas tout fait vrai. . . Nous le verrons avec le mot cl protected. Le compilateur est le programme qui transforme vos codes sources en byte code.

100

LE PRINCIPE DE L'HRITAGE
puli lss gpitle extends ille{ puli gpitle@A{ thisFnomille a 4toto4Y } }

Vous allez avoir une belle erreur de compilation ! Dans notre classe Capitale, nous ne pouvons pas utiliser directement les attributs de la classe Ville. Pourquoi cela ? Tout simplement parce les variables de la classe Ville sont dclares private. C'est ici que le nouveau mot cl protected fait son entre. En fait, seules les mthodes et les variables dclares public ou protected peuvent tre utilises dans une classe hrite ; le compilateur rejette votre demande lorsque vous tentez d'accder des ressources prives d'une classe mre ! Remplacer private par protected dans la dclaration de variables ou de mthodes de la classe Ville aura pour eet de les protger des utilisateurs de la classe tout en permettant aux objets enfants d'y accder. Donc, une fois les variables et mthodes prives de la classe mre dclares en protected, notre objet Capitale aura accs celles-ci ! Ainsi, voici la dclaration de nos variables dans notre classe Ville revue et corrige :
puli lss ille { puli stti int nresnstnes a HY proteted stti int nresnstnesfis a HY proteted tring nomilleY proteted tring nomysY proteted int nreritntsY proteted hr tegorieY } GGout le reste est identiqueF

Notons un point important avant de continuer. Contrairement au C++, Java ne gre pas les hritages multiples : une classe drive 5 ne peut hriter que d'une seule classe mre ! Vous n'aurez donc jamais ce genre de classe :
lss egrfeusefionique extends egrfeuseeirgomprimeD egrfeusewnuelle{ }

La raison est toute simple : si nous admettons que nos classes AgrafeuseAirComprime et AgrafeuseManuelle ont toutes les deux une mthode agrafer() et que vous ne rednissez pas cette mthode dans l'objet AgrafeuseBionique, la JVM ne saura pas quelle mthode utiliser et, plutt que de forcer le programmeur grer les cas d'erreur, les concepteurs du langage ont prfr interdire l'hritage multiple.
5. Je rappelle qu'une classe drive est aussi appele classe lle.

101

CHAPITRE 10. L'HRITAGE prsent, continuons la construction de notre objet hrit : nous allons agrmenter notre classe Capitale. Comme je vous l'avais dit, ce qui direnciera nos objets Capitale de nos objets Ville sera la prsence d'un nouveau champ : le nom d'un monument. Cela implique que nous devons crer un constructeur par dfaut et un constructeur d'initialisation pour notre objet Capitale. Avant de foncer tte baisse, il faut que vous sachiez que nous pouvons faire appel aux variables de la classe mre dans nos constructeurs grce au mot cl super. Cela aura pour eet de rcuprer les lments de l'objet de base, et de les envoyer notre objet hrit. Dmonstration :
lss gpitle extends ille { privte tring monumentY GGgonstruteur pr dfut puli gpitle@A{ GGge mot l ppelle le onstruteur de l lsse mre super@AY monument a 4uun4Y }

Si vous essayez nouveau le petit exemple que je vous avais montr un peu plus haut, vous vous apercevrez que le constructeur par dfaut fonctionne toujours. . . Et pour cause : ici, super() appelle le constructeur par dfaut de l'objet Ville dans le constructeur de Capitale. Nous avons ensuite ajout un monument par dfaut. Cependant, la mthode decrisToi() ne prend pas en compte le nom d'un monument. . . Eh bien le mot cl super() fonctionne aussi pour les mthodes de classe, ce qui nous donne une mthode decrisToi() un peu dirente, car nous allons lui ajouter le champ president pour notre description :
lss gpitle extends ille { privte tring monumentY puli gpitle@A{ GGge mot l ppelle le onstruteur de l lsse mre super@AY monument a 4uun4Y } puli tring derisoi@A{ tring str a superFderisoi@A C 4n t aabb4 C thisFmonumentC 4 en est un monument4Y ystemFoutFprintln@4snvotion de superFderisoi@A4AY ystemFoutFprintln@superFderisoi@AAY return strY }

102

LE PRINCIPE DE L'HRITAGE Si vous relancez les instructions prsentes dans le main depuis le dbut, vous obtiendrez quelque chose comme sur la gure 10.2.

Figure

10.2  Utilisation de super

J'ai ajout les instructions System.out.println an de bien vous montrer comment les choses se passent. Bon, d'accord : nous n'avons toujours pas fait le constructeur d'initialisation de Capitale. Eh bien ? Qu'attendons-nous ?
puli lss gpitle extends ille { privte tring monumentY GGgonstruteur pr dfut puli gpitle@A{ GGge mot l ppelle le onstruteur de l lsse mre super@AY monument a 4uun4Y } GGgonstruteur d9initilistion de pitle puli gpitle@tring nomD int hD tring pysD tring monumentA{ super@nomD hD pysAY thisFmonument a monumentY } GBB B hesription d9une pitle B dreturn tring retourne l desription de l9ojet BG puli tring derisoi@A{ tring str a superFderisoi@A C 4n t aabb4 C thisFmonument C 4en est un monument4Y return strY } GBB B dreturn le nom du monument BG puli tring getwonument@A { return monumentY } GGhfinit le nom du monument

103

CHAPITRE 10. L'HRITAGE


puli void setwonument@tring monumentA { thisFmonument a monumentY }

Copier ce code Code web : 403242 

Les commentaires que vous pouvez voir sont ce que l'on appelle des commentaires JavaDoc 6 : ils permettent de crer une documentation pour votre code. Vous pouvez faire le test avec Eclipse en allant dans le menu Project/Generate JavaDoc.
Dans le constructeur d'initialisation de notre Capitale, vous remarquez la prsence de super(nom, hab, pays);. Dicile de ne pas le voir. . . Cette ligne de code joue le mme rle que celui que nous avons prcdemment vu avec le constructeur par dfaut. Sauf qu'ici, le constructeur auquel super fait rfrence prend trois paramtres : ainsi, super doit prendre ces paramtres. Si vous ne lui mettez aucun paramtre, super() renverra le constructeur par dfaut de la classe Ville. Testez le code ci-dessous, il aura pour rsultat la gure 10.3.
gpitle p a new gpitle@4ris4D TSRWVUD 4prne4D 4l tour iiffel4AY ystemFoutFprintln@4n4CpFderisoi@AAY

Figure

10.3  Classe Capitale avec constructeur

Je vais vous interpeller une fois de plus : vous venez de faire de la mthode decrisToi() une mthode polymorphe, ce qui nous conduit sans dtour ce qui suit.

Le polymorphisme
Voici encore un des concepts fondamentaux de la programmation oriente objet : le polymorphisme. Ce concept complte parfaitement celui de l'hritage, et vous allez voir que le polymorphisme est plus simple qu'il n'y parat. Pour faire court, nous pouvons le dnir en disant qu'il permet de manipuler des objets sans vraiment connatre leur type.
6. Souvenez-vous, je vous en ai parl dans le tout premier chapitre de ce livre.

104

LE POLYMORPHISME Dans notre exemple, vous avez vu qu'il susait d'utiliser la mthode decrisToi() sur un objet Ville ou sur un objet Capitale. On pourrait construire un tableau d'objets et appeler decrisToi() sans se soucier de son contenu : villes, capitales, ou les deux. D'ailleurs, nous allons le faire. Essayez ce code :
GGhfinition d9un tleu de villes null ille tleu a new illeTY GGhfinition d9un tleu de noms de villes et un utre de nomres d9hitnts tring t a {4wrseille4D 4lille4D 4en4D 4lyon4D 4pris4D 4nntes4}Y int tP a {IPQRSTD UVRSTD TSRWVUD USVQPITSD ISWRD PIQ}Y GGves trois premiers lments du tleu seront des villesD GGet le resteD des pitles for@int i a HY i ` TY iCCA{ if @i `QA{ ille a new ille@tiD tPiD 4frne4AY tleui a Y } else{ gpitle g a new gpitle@tiD tPiD 4frne4D 4l tour iiffel4AY tleui a gY }

GGsl ne nous reste plus qu9 drire tout notre tleu 3 for@ille v X tleuA{ ystemFoutFprintln@vFderisoi@AC4n4AY }

Copier ce code Code web : 269087  Rsultat : la gure 10.4. Nous crons un tableau de villes contenant des villes et des capitales 7 grce notre premire boucle for. Dans la seconde, nous achons la description de ces objets. . . et vous voyez que la mthode polymorphe decrisToi() fait bien son travail ! Vous aurez sans doute remarqu que je n'utilise que des objets Ville dans ma boucle : on appelle ceci la covariance des variables ! Cela signie qu'une variable objet peut contenir un objet qui hrite du type de cette variable. Dans notre cas, un objet de type Ville peut contenir un objet de type Capitale. Dans ce cas, on dit que Ville est la superclasse de Capitale. La covariance est ecace dans le cas o la classe hritant rednit certaines mthodes de sa superclasse.
7. Nous avons le droit de faire a, car les objets Capitale sont aussi des objets Ville.

105

CHAPITRE 10. L'HRITAGE

Figure

10.4  Test de polymorphisme

Attention ne pas confondre la surcharge de mthode avec une mthode polymorphe.


 Une mthode surcharge dire de la mthode originale par le nombre ou le type des paramtres qu'elle prend en entre.  Une mthode polymorphe a un squelette identique la mthode de base, mais traite les choses diremment. Cette mthode se trouve dans une autre classe et donc, par extension, dans une autre instance de cette autre classe. Vous devez savoir encore une chose sur l'hritage. Lorsque vous crez une classe (Ville, par exemple), celle-ci hrite, de faon tacite, de la classe Object prsente dans Java. Toutes nos classes hritent donc des mthodes de la classe Object, comme equals() qui prend un objet en paramtre et qui permet de tester l'galit d'objets. Vous vous en tes d'ailleurs servis pour tester l'galit de String() dans la premire partie de ce livre. Donc, en rednissant une mthode de la classe Object dans la classe Ville, nous pourrions utiliser la covariance. La mthode de la classe Object la plus souvent rednie est toString() : elle retourne un String dcrivant l'objet en question (comme notre mthode decrisToi()). Nous allons donc copier la procdure de la mthode decrisToi() dans une nouvelle mthode de la classe Ville : toString(). Voici son code :
puli tring totring@A{ return 4t4CthisFnomilleC4 est une ville de 4CthisFnomysC 4D elle omporte X 4CthisFnreritntC 4 ab elle est don de tgorie X 4CthisFtegorieY }

Nous faisons de mme dans la classe Capitale :


puli tring totring@A{

106

LE POLYMORPHISME
tring str a superFtotring@A C 4n t aabb4 C thisFmonument C 4 en est un monument4Y return strY

Maintenant, testez ce code :


GGhfinition d9un tleu de villes null ille tleu a new illeTY GGhfinition d9un tleu de noms de illes et un utre de nomres d9hitnts tring t a {4wrseille4D 4lille4D 4en4D 4lyon4D 4pris4D 4nntes4}Y int tP a {IPQRSTD UVRSTD TSRWVUD USVQPITSD ISWRD PIQ}Y GGves trois premiers lments du tleu seront des illes GGet le reste des pitles for@int i a HY i ` TY iCCA{ if @i `QA{ ille a new ille@tiD tPiD 4frne4AY tleui a Y } else{ gpitle g a new gpitle@tiD tPiD 4frne4D 4l tour iiffel4AY tleui a gY }

GGsl ne nous reste plus qu9 drire tout notre tleu 3 for@yjet oj X tleuA{ ystemFoutFprintln@ojFtotring@AC4n4AY }

Vous pouvez constater qu'il fait exactement la mme chose que le code prcdent ; nous n'avons pas nous soucier du type d'objet pour acher sa description. Je pense que vous commencez entrevoir la puissance de Java !

Attention : si vous ne rednissez pas ou ne  polymorphez  pas la mthode d'une classe mre dans une classe lle (exemple de toString()), l'appel de celle-ci avec un objet lle, c'est la mthode de la classe mre qui sera invoque !
Une prcision s'impose : si vous avez un objet v de type Ville, par exemple, que vous n'avez pas redni la mthode toString() et que vous testez ce code :
ystemFoutFprintln@vAY

. . . vous appellerez automatiquement la mthode toString() de la classe Object ! Mais 107

CHAPITRE 10. L'HRITAGE ici, comme vous avez redni la mthode toString() dans votre classe Ville, ces deux instructions sont quivalentes :
ystemFoutFprintln@vFtotring@AAY GGist quivlent ystemFoutFprintln@vAY

Pour plus de clart, je conserverai la premire syntaxe, mais il est utile de connatre cette alternative. Pour clarier un peu tout a, vous avez accs aux mthodes public et protected de la classe Object ds que vous crez une classe objet (grce l'hritage tacite). Vous pouvez donc utiliser lesdites mthodes ; mais si vous ne les rednissez pas, l'invocation se fera sur la classe mre avec les traitements de la classe mre. Si vous voulez un exemple concret de ce que je viens de vous dire, vous n'avez qu' retirer la mthode toString() dans les classes Ville et Capitale : vous verrez que le code de la mthode main fonctionne toujours, mais que le rsultat n'est plus du tout pareil, car l'appel de la mthode toString(), la JVM va regarder si celle-ci existe dans la classe appelante et, comme elle ne la trouve pas, elle remonte dans la hirarchie jusqu' arriver la classe Object. . .

Vous devez savoir qu'une mthode n'est invocable par un objet que si celui-ci dnit ladite mthode.
Ainsi, ce code ne fonctionne pas :
puli lss dzI { puli stti void min@tring rgsA{ ille tleu a new illeTY tring t a {4wrseille4D 4lille4D 4en4D 4lyon4D 4pris4D 4nntes4}Y int tP a {IPQRSTD UVRSTD TSRWVUD USVQPITSD ISWRD PIQ}Y for@int i a HY i ` TY iCCA{ if @i `QA{ ille a new ille@tiD tPiD 4frne4AY tleui a Y } else{ gpitle g a new gpitle@tiD tPiD 4frne4D 4l tour iiffel4AY tleui a gY }

GGsl ne nous reste plus qu9 drire tout notre tleu 3 for@yjet v X tleuA{

108

LE POLYMORPHISME
ystemFoutFprintln@vFderisoi@AC4n4AY

Pour qu'il fonctionne, vous devez dire la JVM que la rfrence de type Object est en fait une rfrence de type Ville, comme ceci : ((Ville)v).decrisToi();. Vous transtypez la rfrence v en Ville par cette syntaxe. Ici, l'ordre des oprations s'eectue comme ceci :  vous transtypez la rfrence v en Ville ;  vous appliquez la mthode decrisToi() la rfrence appelante, c'est--dire, ici, une rfrence Object change en Ville. Vous voyez donc l'intrt des mthodes polymorphes : grce elles, vous n'avez plus vous soucier du type de variable appelante. Cependant, n'utilisez le type Object qu'avec parcimonie. Il y a deux autres mthodes qui sont trs souvent rednies :  public boolean equals(Object o), qui permet de vrier si un objet est gal un autre ;  public int hashCode(), qui attribue un code de hashage un objet. En gros, elle donne un identiant un objet. Notez que cet identiant sert plus catgoriser votre objet qu' l'identier formellement.

Il faut garder en tte que ce n'est pas parce que deux objets ont un mme code de hashage qu'ils sont gaux 8 ; par contre, deux objets gaux ont forcment le mme code de hashage !
Voil quoi pourraient ressembler ces deux mthodes pour notre objet Ville :
puli int hshgode@A{ GGyn utilise ii l mthode hshgode de l9ojet tring return @thisFnomysFhshgode@ACthisFnomilleFhshgode@AAY } puli oolen equls@ille vA{ return @thisFhshgode@A aa vFhshgode@A 88 thisFgetxomreritnt@A aa vFgetxomreritnt@AAY }

Nous avons donc dni que le code de hashage de nos objets Ville est fonction du nom du pays et du nom de la ville, que la mthode equals doit prendre en paramtre des objets Ville 9 et que deux objets Ville sont gaux s'ils ont le mme code de hashage ainsi que le mme nombre d'habitants.
8. En eet, deux objets peuvent avoir la mme  catgorie  et tre dirents. . . 9. Elle peut galement recevoir des classes lles de Ville.

109

CHAPITRE 10. L'HRITAGE Il existe encore un type de mthodes dont je ne vous ai pas encore parl : le type final. Une mthode signe final est ge, vous ne pourrez jamais la rednir 10 .
puli finl int mwethode@A{ GGwthode ne pouvnt ps tre surhrge }

Il existe aussi des classes dclares final. Vous avez compris que ces classes sont immuables. . . Et vous ne pouvez donc pas faire hriter un objet d'une classe dclare final !

En rsum
 Une classe hrite d'une autre classe par le biais du mot cl extends.  Une classe ne peut hriter que d'une seule classe.  Si aucun constructeur n'est dni dans une classe lle, la JVM en crera un et appellera automatiquement le constructeur de la classe mre.  La classe lle hrite de toutes les proprits et mthodes public et protected de la classe mre.  Les mthodes et les proprits private d'une classe mre ne sont pas accessibles dans la classe lle.  On peut rednir une mthode hrite, c'est--dire qu'on peut changer tout son code.  On peut utiliser le comportement d'une classe mre par le biais du mot cl super.  Grce l'hritage et au polymorphisme, nous pouvons utiliser la covariance des variables.  Si une mthode d'une classe mre n'est pas rednie ou  polymorphe , l'appel de cette mthode par le biais d'un objet enfant, c'est la mthode de la classe mre qui sera utilise.  Vous ne pouvez pas hriter d'une classe dclare final.  Une mthode dclare final n'est pas rednissable.

10. La mthode getClass() de la classe Object est un exemple de ce type de mthode : vous ne pourrez pas la rednir.

110

Chapitre

11
Dicult :

Modliser ses objets grce UML

ans ce chapitre, nous allons dcouvrir le principe de modlisation d'objet. Le sigle UML signie Unied Modeling Language : traduisez par  langage de modlisation uni . Il ne s'agit pas d'un langage de programmation, mais plutt d'une mthode de modlisation. La mthode Merise, par exemple, en est une autre. En fait, lorsque vous programmez en orient objet, il vous sera sans doute utile de pouvoir schmatiser vos classes, leur hirarchie, leurs dpendances, leur architecture, etc. L'ide est de pouvoir, d'un simple coup d'il, vous reprsenter le fonctionnement de votre logiciel : imaginez UML un peu comme une partition de musique pour le musicien. Le but de ce chapitre n'est pas de vous transformer en experts UML, mais de vous donner susamment de bases pour mieux apprhender la modlisation et ensuite bien cerner certains concepts de la POO.

111

CHAPITRE 11. MODLISER SES OBJETS GRCE UML

Prsentation d'UML
Je sais que vous tes des Zros avertis en matire de programmation, ainsi qu'en informatique en gnral, mais mettez-vous dans la peau d'une personne totalement dnue de connaissances dans le domaine. Il fallait trouver un langage commun aux commerciaux, aux responsables de projets informatiques et aux dveloppeurs, an que tout ce petit monde se comprenne. Avec UML, c'est le cas. En fait, avec UML, vous pouvez modliser toutes les tapes du dveloppement d'une application informatique, de sa conception la mise en route, grce des diagrammes. Il est vrai que certains de ces diagrammes sont plus adapts pour les informaticiens, mais il en existe qui permettent de voir comment interagit l'application avec son contexte de fonctionnement. . . Et dans ce genre de cas, il est indispensable de bien connatre l'entreprise pour laquelle l'application est prvue. On recourt donc un mode de communication comprhensible par tous : UML. Il existe bien sr des outils de modlisation pour crer de tels diagrammes. En ce qui me concerne, j'utilise argoUML 1 . Tlcharger argoUML Code web : 547686 


Cependant, il en existe d'autres, comme :  boUML,  Together,  Poseidon,  Pyut. . . Avec ces outils, vous pouvez raliser les dirents diagrammes qu'UML vous propose :  le diagramme de use case 2 permet de dterminer les dirents cas d'utilisation d'un programme informatique ;  le diagramme de classes ; c'est de celui-l que nous allons nous servir. Il permet de modliser des classes ainsi que les interactions entre elles ;  les diagrammes de squences, eux, permettent de visualiser le droulement d'une application dans un contexte donn ;  et d'autres encore. . . La gure 11.1 reprsente un exemple de diagramme de classes. Vous avez d remarquer qu'il reprsente les classes que nous avons rencontres dans les chapitres prcdents. Je ne vous cache pas qu'il s'agit d'une version simplie. . . En eet, vous pouvez constater que je n'ai pas fait gurer les mthodes dclares public de la classe Object, ni celles des classes que nous avons codes. Je ne vais pas vous apprendre utiliser argoUML, mais plutt lire un diagramme. En eet, dans certains cas, il est utile de modliser les classes et l'interaction entre celles-ci, ne serait-ce que pour disposer de plus de recul sur son travail. Une autre raison cela est que certains concepts de programmation sont plus faciles expliquer avec un diagramme qu'avec
1. Il a le mrite d'tre gratuit et crit en Java. . . donc multi-plates-formes. 2. Cas d'utilisation.

112

MODLISER SES OBJETS

Figure

11.1  Exemple de diagramme de classes

de longs discours. . .

Modliser ses objets


prsent, nous allons apprendre lire un diagramme de classes. Vous avez devin qu'une classe est modlise sous la forme reprsente sur la gure 11.2.

Figure

11.2  Classe en UML

Voici une classe nomme ObjetA qui a comme attributs :  numero de type int ;  nom de type String ;  bool de type boolean. Ses mthodes sont :  getNom() qui retourne une chane de caractres ;  setNom() qui ne renvoie rien ;  afficher() qui renvoie galement une chane de caractres. La porte des attributs et des mthodes n'est pas reprsente ici. Vous voyez, la modlisation d'un objet est toute simple et trs comprhensible ! 113

CHAPITRE 11. MODLISER SES OBJETS GRCE UML Maintenant, intressons-nous aux interactions entre objets.

Modliser les liens entre les objets


Vous allez voir : les interactions sont, elles aussi, trs simples modliser. En fait, comme vous l'avez vu avec l'exemple, les interactions sont modlises par des ches de plusieurs sortes. Nous aborderons ici celles dont nous pouvons nous servir dans l'tat actuel de nos connaissances (au fur et mesure de la progression, d'autres ches apparatront). Regardez la gure 11.3.

Figure

11.3  Reprsentation de l'hritage

Sur ce diagramme, vous remarquez un deuxime objet qui dispose, lui aussi, de paramtres. Ne vous y trompez pas, ObjetB possde galement les attributs et les mthodes de la classe ObjetA. D'aprs vous, pourquoi ? C'est parce que la che qui relie nos deux objets signie  extends . En gros, vous pouvez lire ce diagramme comme suit : l'ObjetB hrite de l'ObjetA, ou encore ObjetB est un ObjetA. Nous allons voir une autre che d'interaction. Je sais que nous n'avons pas encore rencontr ce cas de gure, mais il est simple comprendre. De la mme faon que nous pouvons utiliser des objets de type String dans des classes que nous dveloppons, nous pouvons aussi utiliser comme variable d'instance, ou de classe, un objet que nous avons cod. La gure 11.4 modlise ce cas. Dans cet exemple simpliste, nous avons toujours notre hritage entre un objet A et un objet B, mais dans ce cas, l'ObjetA (et donc l'ObjetB) possde une variable de classe de type ObjetC, ainsi qu'une mthode dont le type de retour est ObjetC (car la mthode retourne un ObjetC). Vous pouvez lire ce diagramme comme suit : l'ObjetA a un ObjetC (donc une seule instance d'ObjetC est prsente dans ObjetA). Voici le code Java correspondant ce diagramme. 114

MODLISER LES LIENS ENTRE LES OBJETS

Figure

11.4  Reprsentation de l'appartenance

Fichier ObjetA.java
puli lss yjete{ proteted yjetg oj a new yjetg@AY puli yjetg getyjet@A{ return ojY }

Fichier ObjetB.java
puli lss yjetf extends yjete{ }

Fichier ObjetC.java
puli lss yjetg{ }

Il reste une dernire che que nous pouvons mentionner, car elle ne dire que lgrement de la premire. Un diagramme la mettant en uvre est reprsent sur la gure 11.5. Ce diagramme est identique au prcdent, l'exception de l'ObjetD. Nous devons le lire comme ceci : l'ObjetA est compos de plusieurs instances d'ObjetD. Vous pouvez d'ailleurs remarquer que la variable d'instance correspondante est de type tableau. . . Voici le code Java correspondant. 115

CHAPITRE 11. MODLISER SES OBJETS GRCE UML

Figure

11.5  Reprsentation de la composition

Fichier ObjetA.java
puli lss yjete{ proteted yjetg oj a new yjetg@AY proteted yjeth ojh a new yjethIHY puli yjetg getyjet@A{ return ojY } puli yjeth getyjeth@A{ return ojhY }

Fichier ObjetB.java
puli lss yjetf extends yjete{ }

Fichier ObjetC.java
puli lss yjetg{ }

Fichier ObjetD.java
puli lss yjeth{ }

Il est bien vident que ces classes ne font strictement rien. Je les ai utilises titre d'exemple pour la modlisation. . .
Voil, c'en est ni pour le moment. Attendez-vous donc rencontrer des diagrammes dans les prochains chapitres. . . 116

MODLISER LES LIENS ENTRE LES OBJETS

En rsum
     UML vous permet de reprsenter les liens entre vos classes. Vous pouvez y modliser leurs attributs et leurs mthodes. Vous pouvez reprsenter l'hritage avec une che signiant  est un . Vous pouvez reprsenter l'appartenance avec une che signiant  a un . Vous pouvez reprsenter la composition avec une che signiant  est compos de .

117

CHAPITRE 11. MODLISER SES OBJETS GRCE UML

118

Chapitre

12
Dicult :

Les packages

orsque nous avons t confronts pour la premire fois aux packages, c'tait pour importer la classe Scanner via l'instruction import java.util.Scanner;. Le fonctionnement des packages est simple comprendre : ce sont comme des dossiers permettant de ranger nos classes. Charger un package nous permet d'utiliser les classes qu'il contient. Il n'y aura rien de franchement compliqu dans ce chapitre si ce n'est que nous reparlerons un peu de la porte des classes Java.

119

CHAPITRE 12. LES PACKAGES

Cration d'un package


L'un des avantages des packages est que nous allons y gagner en lisibilit dans notre package par dfaut, mais aussi que les classes mises dans un package sont plus facilement transportables d'une application l'autre. Pour cela, il vous sut d'inclure le dossier de votre package dans un projet et d'y importer les classes qui vous intressent ! Pour crer un nouveau package, cliquez simplement sur cette icne 1 (gure 12.1).

Figure

12.1  Nouveau package

Une bote de dialogue va s'ouvrir et vous demander le nom de votre package (gure 12.2).

Figure

12.2  Nom du package

Il existe aussi une convention de nommage pour les packages :  ceux-ci doivent tre crits entirement en minuscules ;  les caractres autoriss sont alphanumriques (de a z, de 0 9) et peuvent contenir des points (.) ;  tout package doit commencer par com, edu, gov, mil, net, org ou les deux lettres identiant un pays 2 , fr correspond France, en correspond England. . .  aucun mot cl Java ne doit tre prsent dans le nom, sauf si vous le faites suivre d'un  _ , ainsi :  com.sdz.package n'est pas un nom de package valide,  com.sdz.package_ est un nom de package valide.
1. Vous pouvez aussi eectuer un clic droit puis New Package. 2. ISO Standard 3166, 1981.

120

DROITS D'ACCS ENTRE LES PACKAGES Comme cet ouvrage est la version papier du cours prsent sur le Site du Zro, j'ai pris le nom l'envers : sdz.com nous donne com.sdz. Autre exemple, mes packages ont tendance s'appeler com.cysboy.<nom>. Pour le cas qui nous occupe, appelons-le com.sdz.test. Cliquez sur  Finish  pour crer le package. Et voil : celui-ci est prt l'emploi.

Je vous invite aller voir dans le dossier o se trouvent vos codes sources : vous constaterez qu'il y a l'arborescence du dossier com/sdz/test dans votre dossier src.
Vous conviendrez que la cration d'un package est trs simple. Cependant, je ne peux pas vous laisser sans savoir que la porte de vos classes est aecte par les packages. . .

Droits d'accs entre les packages


Lorsque vous avez cr votre premire classe, vous avez vu qu'Eclipse met systmatiquement le mot cl  public  devant la dclaration de la classe. Je vous avais alors dit que public class Ville et class Ville taient sensiblement dirents et que le mot cl  public  inuait sur la porte de notre classe. En fait, une classe dclare avec le mot cl  public  sera visible mme l'extrieur de son package, les autres ne seront accessibles que depuis l'intrieur du package : on dit que leur porte est default. An de vous prouver mes dires, je vous invite crer un second package : je l'ai appel com.sdz.test2. Dans le premier package, com.sdz.test, crez une classe A de porte public et une classe B de porte default, comme ceci 3 :
pkge omFsdzFtestY lss f { puli tring str a44Y } pkge omFsdzFtestY puli lss e { puli f a new f@AY }

Vous aurez remarqu que les classes contenues dans un package ont en toute premire instruction la dclaration de ce package.
Maintenant que cela est fait, an de faire le test, crez une classe contenant la mthode main, toujours dans le mme package, comme ceci :
3. J'ai volontairement dclar les variables d'instance public an d'allger l'exemple.

121

CHAPITRE 12. LES PACKAGES


pkge omFsdzFtestY puli lss win { puli stti void min@tring rgsA{ e a new e@AY f a new f@AY GGeuun prolme ii } }

Ce code, bien qu'il ne fasse rien, fonctionne trs bien : aucun problme de compilation, entre autres. Maintenant, faites un copier-coller de la classe ci-dessus dans le package com.sdz.test2. Vous devriez avoir le rsultat reprsent sur la gure 12.3.

Figure

12.3  Problme de porte de classe

Vous pouvez constater qu'Eclipse n'aime ni l'instruction import com.sdz.test.B, ni l'instruction B b = new B(); : cela est d la dclaration de notre classe. J'irai mme plus loin : si vous essayez de modier la variable d'instance de l'objet A, vous aurez le mme problme. Donc, ceci : a.b.str = "toto"; n'est pas non plus autoris dans ce package ! La seule faon de corriger le problme est de dclarer la classe B public . Rappelez-vous que seule la classe A avait t dclare ainsi.

En rsum
 Un package est un ensemble de dossiers et de sous-dossiers.  Le nom du package est soumis une convention de nommage.  Si vous voulez utiliser un mot cl Java dans le nom de votre package, vous devez le faire suivre d'un  _ .  Les classes dclares public sont visibles depuis l'extrieur du package qui les contient.  Les classes n'ayant pas t dclares public ne sont pas visibles depuis l'extrieur du package qui les contient.  Si une classe dclare public dans son package a une variable d'un type ayant une porte default, cette dernire ne pourra pas tre modie depuis l'extrieur de son package. 122

Chapitre

13
Dicult :

Les classes abstraites et les interfaces

ous voil de retour avec deux fondements du langage Java. Je vais essayer de faire simple : derrire ces deux notions se cache la manire dont Java vous permet de structurer votre programme. Grce aux chapitres prcdents, vous vous rendez compte que vos programmes Java regorgeront de classes, avec de l'hritage, des dpendances, de la composition. . . An de bien structurer vos programmes (on parle d'architecture logicielle ), vous allez vous creuser les mninges pour savoir o ranger des comportements d'objets :  dans la classe mre ?  dans la classe lle ? Comment obtenir une structure assez souple pour pallier les problmes de programmation les plus courants ? La rponse est dans ce chapitre.

123

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Les classes abstraites


Une classe abstraite est quasiment identique une classe normale. Oui, identique aux classes que vous avez maintenant l'habitude de coder. Cela dit, elle a tout de mme une particularit : vous ne pouvez pas l'instancier ! Vous avez bien lu. Imaginons que nous ayons une classe A dclare abstraite. Voici un code qui ne compilera pas :
puli lss est{ puli stti void min@tring rgsA{ e oj a new e@AY GGirreur de ompiltion 3 } }

Pour bien en comprendre l'utilit, il vous faut un exemple de situation (de programme, en fait) qui le requiert. Imaginez que vous tes en train de raliser un programme qui gre dirents types d'animaux 1 . Dans ce programme, vous aurez des loups, des chiens, des chats, des lions et des tigres. Mais vous n'allez tout de mme pas faire toutes vos classes btement : il va de soi que tous ces animaux ont des points communs ! Et qui dit points communs dit hritage. Que pouvons-nous dnir de commun tous ces animaux ? Le fait qu'ils aient une couleur, un poids, un cri, une faon de se dplacer, qu'ils mangent et boivent quelque chose. Nous pouvons donc crer une classe mre : appelons-la Animal. Avec ce que nous avons dgag de commun, nous pouvons lui dnir des attributs et des mthodes. Voici donc ce quoi ressemblent nos classes tant qu' prsent (gure 13.1).

Figure

13.1  Classe Animal

Nous avons bien notre classe mre Animal et nos animaux qui en hritent. prsent, laissez-moi vous poser une question.
1. Oui, je sais : l'exemple est bte, mais il a le mrite d'tre simple comprendre.

124

LES CLASSES ABSTRAITES

Vu que notre classe Animal est public, qu'est cens faire un objet Animal ? Quel est son poids, sa couleur, que mange-t-il ?
Si nous avons un morceau de code qui ressemble ceci :
puli lss est{ puli stti void min@tring rgsA{ eniml ni a new eniml@AY @@voupAniAFmnger@AY GGue doitEil fire c } }

. . . personnellement, je ne sais pas ce que mange un objet Animal. . . Vous conviendrez

que toutes les classes ne sont pas bonnes tre instancies !

C'est l qu'entrent en jeu nos classes abstraites. En fait, ces classes servent dnir une superclasse : par l, vous pouvez comprendre qu'elles servent essentiellement crer un nouveau type d'objets. Voyons maintenant comment crer une telle classe.

Une classe Animal trs abstraite


En fait, il existe une rgle pour qu'une classe soit considre comme abstraite. Elle doit tre dclare avec le mot cl abstract. Voici un exemple illustrant mes dires :
strt lss eniml{ }

Une telle classe peut contenir la mme chose qu'une classe normale. Ses enfants pourront utiliser tous ses lments dclars 2 (attributs et mthodes). Cependant, ce type de classe permet de dnir des mthodes abstraites. . . mthodes qui prsentent une particularit : elle n'ont pas de corps ! En voici un exemple :
strt lss eniml{ strt void mnger@AY GGne mthode strite }

Vous voyez pourquoi on dit  mthode abstraite  : dicile de voir ce que cette mthode sait faire. . .

Retenez bien qu'une mthode abstraite n'est compose que de l'en-tte de la mthode suivie d'un point-virgule  ; .
2. lments dclars public ou protected, nous sommes d'accord.

125

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES Il faut que vous sachiez qu'une mthode abstraite ne peut exister que dans une classe abstraite. Si, dans une classe, vous avez une mthode dclare abstraite, vous devez dclarer cette classe comme tant abstraite. Voyons quoi cela peut servir. Vous avez vu les avantages de l'hritage et du polymorphisme. Eh bien nos classes enfants hriteront aussi des mthodes abstraites, mais tant donn que celles-ci n'ont pas de corps, nos classes enfants seront obliges de rednir ces mthodes ! Elles prsentent donc des mthodes polymorphes, ce qui implique que la covariance des variables pointe nouveau le bout de son nez :
puli lss est{ puli stti void min@tring rgsA{ eniml loup a new voup@AY eniml hien a new ghien@AY loupFmnger@AY hienFrier@AY } }

Attends ! Tu nous as dit qu'on ne pouvait pas instancier de classe abstraite !


Et je maintiens mes dires : nous n'avons pas instanci notre classe abstraite. Nous avons instanci un objet Loup que nous avons mis dans un objet de type Animal 3 . Vous devez vous rappeler que l'instance se cre avec le mot cl new. En aucun cas, le fait de dclarer une variable d'un type de classe donn  ici, Animal  n'est une instanciation ! Ici, nous instancions un Loup et un Chien. Vous pouvez aussi utiliser une variable de type Object comme rfrence un objet Loup, un objet Chien. . . Vous saviez dj que ce code fonctionne :
puli lss est{ puli stti void min@tring rgsA{ yjet oj a new voup@AY @@voupAojAFmnger@AY } }

En revanche, ceci pose problme :


puli stti void min@tring rgsA{ yjet oj a new voup@AY voup l a ojY GGrolme de rfrene }
3. Il en va de mme pour l'instanciation de la classe Chien.

126

LES CLASSES ABSTRAITES Eh oui ! Vous essayez de mettre une rfrence de type Object dans une rfrence de type Loup : pour avertir la JVM que la rfrence que vous voulez aecter votre objet de type Loup est un Loup, vous devez utiliser le transtypage ! Revoyons notre code :
puli stti void min@tring rgsA{ yjet oj a new voup@AY voup l a @voupAojY GGous prvenez l tw que l rfrene que vous pssez est de type voupF }

Vous pouvez bien videmment instancier directement un objet Loup, un objet Chien, etc.

Pour le moment, nous n'avons de code dans aucune classe ! Les exemples que je vous ai fournis ne font rien du tout, mais ils fonctionneront lorsque nous aurons ajout des morceaux de code nos classes.

toons notre exemple


Nous allons donc ajouter des morceaux de code nos classes. Tout d'abord, tablissons un bilan de ce que nous savons.  Nos objets seront probablement tous de couleur et de poids dirents. Nos classes auront donc le droit de modier ceux-ci.  Ici, nous partons du principe que tous nos animaux mangent de la viande. La mthode manger() sera donc dnie dans la classe Animal.  Idem pour la mthode boire(). Ils boiront tous de l'eau 4 .  Ils ne crieront pas et ne se dplaceront pas de la mme manire. Nous emploierons donc des mthodes polymorphes et dclarerons les mthodes deplacement() et crier() abstraites dans la classe Animal. La gure 13.2 reprsente le diagramme des classes de nos futurs objets. Ce diagramme permet de voir si une classe est abstraite : son nom est alors en italique. Nous voyons bien que notre classe Animal est dclare abstraite et que nos classes lles hritent de celle-ci. De plus, nos classes lles ne rednissent que deux mthodes sur quatre, on en conclut donc que ces deux mthodes doivent tre abstraites. Nous ajouterons deux constructeurs nos classes lles : un par dfaut et un autre comprenant les deux paramtres d'initialisation. cela, nous ajouterons aussi les accesseurs d'usage. Mais dites donc. . . nous pouvons amliorer un peu cette architecture, sans pour autant rentrer dans les dtails ! Vu les animaux prsents, nous aurions pu faire une sous-classe Carnivore, ou encore AnimalDomestique et AnimalSauvage. . . Ici, nous allons nous contenter de faire deux sous-classes : Canin et Felin, qui hriteront d'Animal et dont nos objets eux-mmes hriteront !
4. Je vous voyais venir. . .

127

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Figure

13.2  Hirarchie de nos classes

Nous allons rednir la mthode deplacement() dans cette classe, car nous allons partir du principe que les flins se dplacent d'une certaine faon et les canins d'une autre. Avec cet exemple, nous rviserons le polymorphisme. . . La gure 13.3 correspond notre diagramme mis jour 5 .

Figure

13.3  Nouvelle architecture des classes


Voici les codes Java correspondants.




Copier ces classes Code web : 571397 

5. Vous avez remarqu ? J'ai ajout une mthode toString().

128

LES CLASSES ABSTRAITES

Animal.java
strt lss eniml { proteted tring ouleurY proteted int poidsY proteted void mnger@A{ ystemFoutFprintln@4te mnge de l vindeF4AY } proteted void oire@A{ ystemFoutFprintln@4te ois de l9eu 34AY } strt void deplement@AY strt void rier@AY puli tring totring@A{ tring str a 4te suis un ojet de l 4 C thisFgetglss@A C 4D je suis 4 C thisFouleur C 4D je pse 4 C thisFpoidsY return strY }

Felin.java
puli strt lss pelin extends eniml { void deplement@A { ystemFoutFprintln@4te me dple seul 34AY } }

Canin.java
puli strt lss gnin extends eniml { void deplement@A { ystemFoutFprintln@4te me dple en meute 34AY } }

Chien.java
puli lss ghien extends gnin { puli ghien@A{

129

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES


} puli ghien@tring ouleurD int poidsA{ thisFouleur a ouleurY thisFpoids a poidsY } void rier@A { ystemFoutFprintln@4t9oie sns rison 34AY }

Loup.java
puli lss voup extends gnin { puli voup@A{ } puli voup@tring ouleurD int poidsA{ thisFouleur a ouleurY thisFpoids a poidsY } void rier@A { ystemFoutFprintln@4te hurle l vune en fisnt ouhouh 34AY }

Lion.java
puli lss vion extends pelin { puli vion@A{ } puli vion@tring ouleurD int poidsA{ thisFouleur a ouleurY thisFpoids a poidsY } void rier@A { ystemFoutFprintln@4te rugis dns l svne 34AY }

130

LES CLASSES ABSTRAITES

Tigre.java
puli lss igre extends pelin { puli igre@A{ } puli igre@tring ouleurD int poidsA{ thisFouleur a ouleurY thisFpoids a poidsY } void rier@A { ystemFoutFprintln@4te grogne trs fort 34AY }

Chat.java
puli lss ght extends pelin { puli ght@A{ } puli ght@tring ouleurD int poidsA{ thisFouleur a ouleurY thisFpoids a poidsY } void rier@A { ystemFoutFprintln@4te miule sur les toits 34AY }

Dis donc ! Une classe abstraite ne doit-elle pas comporter une mthode abstraite ?
Je n'ai jamais dit a ! Une classe dclare abstraite n'est pas instanciable, mais rien ne l'oblige comprendre des mthodes abstraites. En revanche, une classe contenant une mthode abstraite doit tre dclare abstraite ! Je vous invite maintenant faire des tests :
puli lss est { puli stti void min@tring rgsA { voup l a new voup@4qris leut4D PHAY lFoire@AY lFmnger@AY

131

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES


lFdeplement@AY lFrier@AY ystemFoutFprintln@lFtotring@AAY

Le jeu d'essai de ce code correspond la gure 13.4.

Figure

13.4  Test d'une classe abstraite

Dans la mthode toString() de la classe Animal, j'ai utilis la mthode getClass() qui  je vous le donne en mille  se trouve dans la classe Object. Celle-ci retourne  class <nom de la classe> .
Dans cet exemple, nous pouvons constater que nous avons un objet Loup.  l'appel de la mthode boire() : l'objet appelle la mthode de la classe Animal.  l'appel de la mthode manger() : idem.  l'appel de la mthode toString() : idem.  l'appel de la mthode deplacement() : c'est la mthode de la classe Canin qui est invoque ici.  l'appel de la mthode crier() : c'est la mthode de la classe Loup qui est appele. Remplacez le type de rfrence (ici, Loup) par Animal, essayez avec des objets Chien, etc. Vous verrez que tout fonctionne. 132

LES INTERFACES

Les interfaces
L'un des atouts majeurs  pour ne pas dire l'atout majeur  de la programmation oriente objet est la rutilisabilit de vos objets. Il est trs commode d'utiliser un objet (voire une architecture) que nous avons dj cr pour une nouvelle application. Admettons que l'architecture que nous avons dveloppe dans les chapitres prcdents forme une bonne base. Que se passerait-il si un autre dveloppeur vous demandait d'utiliser vos objets dans un autre type d'application ? Ici, nous ne nous sommes occups que de l'aspect gnrique des animaux que nous avons crs. Cependant, la personne qui vous a contact, elle, dveloppe une application pour un chenil. La contrainte principale, c'est que vos chiens devront apprendre faire de nouvelles choses telles que :  faire le beau ;  faire des clins ;  faire une  lchouille .

Je ne vois pas le problme. . . Tu n'as qu' ajouter ces mthodes dans la classe Animal !
Ouh l ! Vous vous rendez compte que vous obtiendrez des lions qui auront la possibilit de faire le beau ? Dans ce cas, on n'a qu' mettre ces mthodes dans la classe Chien, mais j'y vois deux problmes :  vous allez devoir mettre en place une convention de nommage entre le programmeur qui va utiliser vos objets et vous. . . Vous ne pourrez pas utiliser la mthode faireCalin(), alors que le programmeur oui ;  si vous faites cela, adieu le polymorphisme ! Vous ne pourrez pas appeler vos objets par le biais d'un supertype. Pour pouvoir accder ces mthodes, vous devrez obligatoirement passer par une rfrence un objet Chien. Pas terrible, tout a. . .

Tu nous as dit que pour utiliser au mieux le polymorphisme, nous devions dnir les mthodes au plus haut niveau de la hirarchie. Alors du coup, il faut rednir un supertype pour pouvoir utiliser le polymorphisme !
Oui, et je vous rappelle que l'hritage multiple est interdit en Java. Et quand je dis interdit, je veux dire que Java ne le gre pas ! Il faudrait pouvoir dvelopper un nouveau supertype et s'en servir dans nos classes Chien. Eh bien nous pouvons faire cela avec des interfaces. En fait, les interfaces permettent de crer un nouveau supertype ; on peut mme en ajouter autant que l'on le veut dans une seule classe ! Quant l'utilisation de nos objets, la convention est toute trouve. . . Pourquoi ? Parce qu'une interface n'est rien d'autre qu'une classe 100 % abstraite ! Allez : venons-en aux faits ! 133

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Votre premire interface


Pour dnir une interface, au lieu d'crire :
puli lss e{ }

. . . il vous sut de faire :


puli interfe s{ }

Voil : vous venez d'apprendre dclarer une interface. Vu qu'une interface est une classe 100 % abstraite, il ne vous reste qu' y ajouter des mthodes abstraites, mais sans le mot cl abstract. Voici des exemples d'interfaces :
puli interfe s{ puli void e@AY puli tring f@AY } puli interfe sP{ puli void g@AY puli tring h@AY }

Et pour faire en sorte qu'une classe utilise une interface, il sut d'utiliser le mot cl implements. Ce qui nous donnerait :
puli lss implements s{ puli void e@A{ GGFFFFFFF } puli tring f@A{ GGFFFFFFF } }

C'est tout. On dit que la classe X implmente l'interface I. Comme je vous le disais, vous pouvez implmenter plusieurs interfaces, et voil comment a se passe :
puli lss implements sD sP{ puli void e@A{ GGFFFFFFF } puli tring f@A{ GGFFFFFFF } puli void g@A{

134

LES INTERFACES
GGFFFFFFF } puli tring h@A{ GGFFFFFFF }

Par contre, lorsque vous implmentez une interface, vous devez obligatoirement rednir les mthodes de l'interface ! Ainsi, le polymorphisme vous permet de faire ceci :
puli stti void min@tring rgsA{ GGeve ette rfreneD vous pouvez utiliser les mthodes de l9interfe s s vr a new @AY GGeve ette rfreneD vous pouvez utiliser les mthodes de l9interfe sP sP vrP a new @AY vrFe@AY vrPFg@AY }

Implmentation de l'interface Rintintin


Voil o nous en sommes
 Nous voulons que nos chiens puissent tre amicaux.  Nous voulons dnir un supertype pour utiliser le polymorphisme.  Nous voulons pouvoir continuer utiliser nos objets comme avant. Comme le titre de cette sous-partie le stipule, nous allons crer l'interface Rintintin pour ensuite l'implmenter dans notre objet Chien. Sous Eclipse, vous pouvez faire File New Interface, ou simplement cliquer sur la che noire ct du  C  pour la cration de classe, et choisir interface (gure 13.5). Voici son code :
puli interfe intintin{ puli void fireglin@AY puli void firevehouille@AY puli void firevefeu@AY }

prsent, il ne nous reste plus qu' implmenter l'interface dans notre classe Chien :
puli lss ghien extends gnin implements intintin {

135

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Figure

13.5  Cration d'une nouvelle interface

puli ghien@A{ } puli ghien@tring ouleurD int poidsA{ thisFouleur a ouleurY thisFpoids a poidsY } void rier@A { ystemFoutFprintln@4t9oie sns rison 34AY } puli void fireglin@A { ystemFoutFprintln@4te te fis un qy gvsx4AY } puli void firevefeu@A { ystemFoutFprintln@4te fis le eu 34AY } puli void firevehouille@A { ystemFoutFprintln@4te fis de grosses lhouillesFFF4AY }

L'ordre des dclarations est primordial. Vous devez mettre l'expression d'hritage avant l'expression d'implmentation, sinon votre code ne compilera pas.
Voici un code que vous pouvez utiliser pour tester le polymorphisme de notre implmentation :
puli lss est { puli stti void min@tring rgsA { GGves mthodes d9un hien ghien a new ghien@4qris leut4D PHAY Foire@AY Fmnger@AY Fdeplement@AY Frier@AY ystemFoutFprintln@Ftotring@AAY ystemFoutFprintln@4EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE4AY

136

LE PATTERN STRATEGY
GGves mthodes de l9interfe Ffireglin@AY Ffirevefeu@AY Ffirevehouille@AY ystemFoutFprintln@4EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE4AY GGtilisons le polymorphisme de notre interfe intintin r a new ghien@AY rFfirevefeu@AY rFfireglin@AY rFfirevehouille@AY } }

Objectif atteint ! Nous sommes parvenus dnir deux superclasses an de les utiliser comme supertypes et de jouir pleinement du polymorphisme. Dans la suite de ce chapitre, nous verrons qu'il existe une faon trs intressante d'utiliser les interfaces grce une technique de programmation appele pattern strategy. Sa lecture n'est pas indispensable, mais cela vous permettra de dcouvrir travers un cas concret comment on peut faire voluer au mieux un programme Java.

Le pattern strategy
Nous allons partir du principe que vous avez un code qui fonctionne, c'est--dire un ensemble de classes lies par l'hritage, par exemple. Nous allons voir ici que, en dpit de la toute-puissance de l'hritage, celui-ci atteint ses limites lorsque vous tes amens modier la hirarchie de vos classes an de rpondre une demande (de votre chef, d'un client. . .). Le fait de toucher votre hirarchie peut amener des erreurs indsirables, voire des absurdits : tout cela parce que vous allez changer une structure qui fonctionne cause de contraintes que l'on vous impose. Pour remdier ce problme, il existe un concept simple (il s'agit mme d'un des fondements de la programmation oriente objet) : l'encapsulation ! Nous allons parler de cette solution en utilisant un design pattern 6 . Un design pattern est un patron de conception, une faon de construire une hirarchie des classes permettant de rpondre un problme. Nous aborderons le pattern strategy, qui va nous permettre de remdier la limite de l'hritage. En eet, mme si l'hritage ore beaucoup de possibilits, il a ses limites.

Posons le problme
Mettez-vous dans la peau de dveloppeurs jeunes et ambitieux d'une toute nouvelle socit qui cre des jeux vido. Le dernier titre en date, Z-Army, un jeu de guerre trs
6. Ou modle

de conception.
137

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES raliste, a t un succs international ! Votre patron est content et vous aussi. Vous vous tes bass sur une architecture vraiment simple an de crer et utiliser des personnages (gure 13.6).

Figure

13.6  Hirarchie des classes

Les guerriers savent se battre tandis que les mdecins soignent les blesss sur le champ de bataille ! Les ennuis commencent maintenant. . . Votre patron vous a con le projet Z-Army2  The return of the revenge , et vous vous dites :  Yes ! Mon architecture fonctionne merveille, je la garde.  Un mois plus tard, votre patron vous convoque dans son bureau et vous dit :  Nous avons fait une tude de march, et il semblerait que les joueurs aimeraient se battre aussi avec les mdecins !  Vous trouvez l'ide sduisante et avez dj pens une solution : dplacer la mthode combattre() dans la superclasse Personnage, an de la rednir dans la classe Medecin et jouir du polymorphisme (gure 13.7) !

Figure

13.7  Dplacement de la mthode combattre()

la seconde tude de march, votre patron vous annonce que vous allez devoir crer des civils, des snipers, des chirurgiens. . . Toute une panoplie de personnages spcialiss dans leur domaine (gure 13.8) ! 138

LE PATTERN STRATEGY

Figure

13.8  Nouveaux personnages

Le code source de ces classes


Copier les classes Code web : 777033 


Personnage.java
puli strt lss ersonnge { GBB B wthode de dplement de personnge BG puli strt void sehepler@AY GBB B wthode que les omttnts utilisent BG puli strt void omttre@AY

Guerrier.java
puli lss querrier extends ersonnge { puli void omttre@A { ystemFoutFprintln@4pusilD pistoletD outeu 3 out e que tu veux 34AY } puli void sehepler@A { ystemFoutFprintln@4te me dple piedF4AY }

139

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Medecin.java
puli lss wedein extends ersonnge{ puli void omttre@A { ystemFoutFprintln@4ive le slpel 34AY } puli void sehepler@A { ystemFoutFprintln@4te me dple piedF4AY } puli void soigner@A{ ystemFoutFprintln@4te soigne les lessuresF4AY }

Civil.java
puli lss givil extends ersonnge{ puli void omttre@A { ystemFoutFprintln@4te ne omts e 34AY } puli void sehepler@A { ystemFoutFprintln@4te me dple piedF4AY }

Chirurgien.java
puli lss ghirurgien extends ersonnge{ puli void omttre@A { ystemFoutFprintln@4te ne omts e 34AY } puli void sehepler@A { ystemFoutFprintln@4te me dple piedF4AY } puli void soigner@A{ ystemFoutFprintln@4te fis des oprtionsF4AY }

Sniper.java
puli lss niper extends ersonnge{ puli void omttre@A {

140

LE PATTERN STRATEGY
ystemFoutFprintln@4te me sers de mon fusil lunette 34AY

puli void sehepler@A { ystemFoutFprintln@4te me dple piedF4AY }

ce stade, vous devriez remarquer que :  le code contenu dans la mthode seDeplacer() est dupliqu dans toutes les classes ; il est identique dans toutes celles cites ci-dessus ;  le code de la mthode combattre() des classes Chirurgien et Civil est lui aussi dupliqu ! La duplication de code est une chose qui peut gnrer des problmes dans le futur. . . Je m'explique. Pour le moment, votre chef ne vous a demand que de crer quelques classes supplmentaires. Qu'en serait-il si beaucoup de classes avaient ce mme code dupliqu ? Il ne manquerait plus que votre chef vous demande de modier nouveau la faon de se dplacer de ces objets, et vous courrez le risque d'oublier d'en modier un ! Et voil les incohrences qui pointeront le bout de leur nez. . .

No problemo ! Tu vas voir. . . Il sut de mettre un comportement par dfaut pour le dplacement et pour le combat dans la superclasse Personnage.
Eectivement, votre ide se tient. Donc, cela nous donne ce qui suit. . .

Personnage.java
puli strt lss ersonnge { puli void sehepler@A{ ystemFoutFprintln@4te me dple piedF4AY } puli void omttre@A{ ystemFoutFprintln@4te ne omts e 34AY }

Guerrier.java
puli lss querrier extends ersonnge { puli void omttre@A { ystemFoutFprintln@4pusilD pistoletD outeu 3 out e que tu veux 34AY } }

141

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Medecin.java
puli lss wedein extends ersonnge{ puli void omttre@A { ystemFoutFprintln@4ive le slpel 34AY } puli void soigner@A{ ystemFoutFprintln@4te soigne les lessuresF4AY }

Civil.java
puli lss givil extends ersonnge{ }

Chirurgien.java
puli lss ghirurgien extends ersonnge{ puli void soigner@A{ ystemFoutFprintln@4te fis des oprtionsF4AY } }

Sniper.java
puli lss niper extends ersonnge{ puli void omttre@A { ystemFoutFprintln@4te me sers de mon fusil lunette 34AY } }

Voici une classe contenant un petit programme an de tester nos classes :
puli stti void min@tring rgsA { ersonnge ters a {new querrier@AD new ghirurgien@AD new givil@AD new niper@AD new wedein@A}Y for@ersonnge p X tersA{ ystemFoutFprintln@4nsnstne de 4 C pFgetglss@AFgetxme@AAY ystemFoutFprintln@4BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB4AY pFomttre@AY pFsehepler@AY } }

Et le rsultat correspond la gure 13.9. 142

LE PATTERN STRATEGY

Figure

13.9  Rsultat du code

Apparemment, ce code vous donne ce que vous voulez ! Plus de redondance. . . Mais une chose me chionne : vous ne pouvez pas utiliser les classes Medecin et Chirurgien de faon polymorphe, vu que la mthode soigner() leur est propre ! On pourrait dnir un comportement par dfaut (ne pas soigner) dans la superclasse Personnage, et le tour serait jou.
puli strt lss ersonnge { puli void sehepler@A{ ystemFoutFprintln@4te me dple piedF4AY } puli void omttre@A{ ystemFoutFprintln@4te ne omts e 34AY } puli void soigner@A{ ystemFoutFprintln@4te ne soigne psF4AY } }

Au mme moment, votre chef rentre dans votre bureau et vous dit :  Nous avons bien rchi, et il serait de bon ton que nos guerriers puissent administrer les premiers soins.  ce moment prcis, vous vous dlectez de votre capacit d'anticipation ! Vous savez que, maintenant, il vous sut de rednir la mthode soigner() dans la classe concerne, et tout le monde sera content ! 143

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES Seulement voil ! Votre chef n'avait pas ni son speech :  Au fait, il faudrait aecter un comportement nos personnages en fonction de leurs armes, leurs habits, leurs trousses de soin. . . Enn, vous voyez ! Les comportements gs pour des personnages de jeux, de nos jours. . . c'est un peu ringard !  Vous commencez voir ce dont il retourne : vous devrez apporter des modications votre code, encore et encore. . . Bon : pour des programmeurs, cela est le train-train quotidien, j'en conviens. Cependant, si nous suivons les consignes de notre chef et que nous continuons sur notre lance, les choses vont se compliquer. . . Voyons cela.

Un problme supplmentaire
Attelons-nous appliquer les modications dans notre programme. Selon les directives de notre chef, nous devons grer des comportements dirents selon les accessoires de nos personnages : il faut utiliser des variables d'instance pour appliquer l'un ou l'autre comportement.

An de simplier l'exemple, nous n'allons utiliser que des objets String.
La gure 13.10 correspond au diagramme des classes de notre programme.

Figure

13.10  Modication de nos classes

Vous avez remarqu que nos personnages possderont des accessoires. Selon ceux-ci, nos personnages feront des choses direntes. Voici les recommandations de notre chef bien-aim :  le guerrier peut utiliser un couteau, un pistolet ou un fusil de sniper ;  le sniper peut utiliser son fusil de sniper ainsi qu'un fusil pompe ;  le mdecin a une trousse simple pour soigner, mais peut utiliser un pistolet ;  le chirurgien a une grosse trousse mdicale, mais ne peut pas utiliser d'arme ;  le civil, quant lui, peut utiliser un couteau seulement quand il en a un ; 144

LE PATTERN STRATEGY  tous les personnages hormis le chirurgien peuvent avoir des baskets pour courir. Il va nous falloir des accesseurs 7 pour ces variables, insrons-les dans la superclasse ! Bon ! Les modications sont faites, les caprices de notre cher et tendre chef sont satisfaits ? Voyons cela tout de suite.


Hirarchie des classes Code web : 959825 

Personnage.java
puli strt lss ersonnge { proteted tring rmes a 44D hussure a 44D sheoin a 44Y puli void sehepler@A{ ystemFoutFprintln@4te me dple piedF4AY } puli void omttre@A{ ystemFoutFprintln@4te ne omts e 34AY } puli void soigner@A{ ystemFoutFprintln@4te ne soigne psF4AY } proteted void setermes@tring rmesA { thisFrmes a rmesY } proteted void setghussure@tring hussureA { thisFhussure a hussureY } proteted void setheoin@tring sheoinA { thisFsheoin a sheoinY }

Guerrier.java
puli lss querrier extends ersonnge { puli void omttre@A { if@thisFrmesFequls@4pistolet4AA ystemFoutFprintln@4ettque u pistolet 34AY else if@thisFrmesFequls@4fusil de sniper4AA ystemFoutFprintln@4ettque u fusil de sniper 34AY
7. Inutile de mettre les mthodes de renvoi (getXXX), nous ne nous servirons que des mutateurs !

145

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES


else } }

ystemFoutFprintln@4ettque u outeu 34AY

Sniper.java
puli lss niper extends ersonnge{ puli void omttre@A { if@thisFrmesFequls@4fusil pompe4AA ystemFoutFprintln@4ettque u fusil pompe 34AY else ystemFoutFprintln@4te me sers de mon fusil lunette 34AY } }

Civil.java
puli lss givil extends ersonnge{ puli void omttre@A{ if@thisFrmesFequls@4outeu4AA ystemFoutFprintln@4ettque u outeu 34AY else ystemFoutFprintln@4te ne omts e 34AY } }

Medecin.java
puli lss wedein extends ersonnge{ puli void omttre@A { if@thisFrmesFequls@4pistolet4AA ystemFoutFprintln@4ettque u pistolet 34AY else ystemFoutFprintln@4ive le slpel 34AY } puli void soigner@A{ if@thisFsheoinFequls@4petit s4AA ystemFoutFprintln@4te peux reoudre des lessuresF4AY else ystemFoutFprintln@4te soigne les lessuresF4AY }

146

LE PATTERN STRATEGY

Chirurgien.java
puli lss ghirurgien extends ersonnge{ puli void soigner@A{ if@thisFsheoinFequls@4gros s4AA ystemFoutFprintln@4te fis des merveillesF4AY else ystemFoutFprintln@4te fis des oprtionsF4AY } }

Voici un programme de test :


puli stti void min@tring rgsA { ersonnge ters a {new querrier@AD new ghirurgien@AD new givil@AD new niper@AD new wedein@A}Y tring termes a {4pistolet4D 4pistolet4D 4outeu4D 4fusil pompe4D 4outeu4}Y for@int i a HY i ` tersFlengthY iCCA{ ystemFoutFprintln@4nsnstne de 4 C tersiFgetglss@AF getxme@AAY ystemFoutFprintln@4BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB4AY tersiFomttre@AY tersiFsetermes@termesiAY tersiFomttre@AY tersiFsehepler@AY tersiFsoigner@AY }

Le rsultat de ce test se trouve sur la gure 13.11. Vous constatez avec merveillement que votre code fonctionne trs bien. Les actions par dfaut sont respectes, les aectations d'actions aussi. Tout est parfait !

Vraiment ? Vous tes srs de cela ? Pourtant, je vois du code dupliqu dans certaines classes ! En plus, nous n'arrtons pas de modier nos classes. . . Dans le premier opus de Z-Army, celles-ci fonctionnaient pourtant trs bien ! Qu'est-ce qui ne va pas ? Je ne comprends pas.
L-dessus, votre patron rentre dans votre bureau pour vous dire :  Les actions de vos personnages doivent tre utilisables la vole et, en fait, les personnages peuvent trs bien apprendre au l du jeu. . .  Les changements s'accumulent, votre code devient de moins en moins lisible et rutilisable, bref c'est l'enfer sur Terre. Faisons un point de la situation :  du code dupliqu s'insinue dans votre code ; 147

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Figure

13.11  Rsultat du test d'accessoires

148

LE PATTERN STRATEGY  chaque modication du comportement de vos personnages, vous tes obligs de retoucher le code source de la (ou des) classe(s) concerne(s) ;  votre code perd en rutilisabilit et du coup, il n'est pas extensible du tout !

Une solution simple et robuste : le pattern strategy


Aprs toutes ces motions, vous allez enn disposer d'une solution ce problme de modication du code source ! Si vous vous souvenez de ce que j'ai dit, un des fondements de la programmation oriente objet est l'encapsulation. Le pattern strategy est bas sur ce principe simple. Bon, vous avez compris que le pattern strategy consiste crer des objets avec des donnes, des mthodes (voire les deux) : c'est justement ce qui change dans votre programme ! Le principe de base de ce pattern est le suivant : isolez ce qui varie dans votre programme et encapsulez-le ! Dj, quels sont les lments qui ne cessent de varier dans notre programme ?  La mthode combattre().  La mthode seDeplacer().  La mthode soigner().

Ce qui serait vraiment grandiose, ce serait d'avoir la possibilit de ne modier que les comportements et non les objets qui ont ces comportements !
L, je vous arrte un moment : vous venez de fournir la solution. Vous avez dit :  Ce qui serait vraiment grandiose, ce serait d'avoir la possibilit de ne modier que les comportements et non les objets qui ont ces comportements . Lorsque je vous ai prsent les diagrammes UML, je vous ai fourni une astuce pour bien direncier les liens entre les objets. Dans notre cas, nos classes hritant de Personnage hritent aussi de ses comportements et, par consquent, on peut dire que nos classes lles sont des Personnage. Les comportements de la classe mre semblent ne pas tre au bon endroit dans la hirarchie. Vous ne savez plus quoi en faire et vous vous demandez s'ils ont vraiment leur place dans cette classe ? Il vous sut de sortir ces comportements de la classe mre, de crer une classe abstraite ou une interface symbolisant ce comportement et d'ordonner votre classe Personnage d'avoir ces comportements. Le nouveau diagramme des classes se trouve sur la gure 13.12. Vous apercevez une nouvelle entit sur ce diagramme, l'interface, facilement reconnaissable, ainsi qu'une nouvelle che symbolisant l'implmentation d'interface entre une classe concrte et une interface. N'oubliez pas que votre code doit tre souple et robuste et que  mme si ce chapitre vous montre les limites de l'hritage  le polymorphisme est inhrent l'hritage 8 .
8. Ainsi qu'aux implmentations d'interfaces.

149

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES

Figure

13.12  Nouveau diagramme des classes

Il faut vous rendre compte qu'utiliser une interface de cette manire revient crer un supertype de variable ; du coup, nous pourrons utiliser les classes hritant de ces interfaces de faon polymorphe sans nous soucier de savoir la classe dont sont issus nos objets ! Dans notre cas, notre classe Personnage comprendra des objets de type EspritCombatif, Soin et Deplacement ! Avant de nous lancer dans le codage de nos nouvelles classes, vous devez observer que leur nombre a considrablement augment depuis le dbut. An de pouvoir gagner en clart, nous allons grer nos direntes classes avec dirents packages. Comme nous l'avons remarqu tout au long de ce chapitre, les comportements de nos personnages sont trop pars pour tre dnis dans notre superclasse Personnage. Vous l'avez dit vous-mmes : il faudrait que l'on ne puisse modier que les comportements et non les classes hritant de notre superclasse ! Les interfaces nous servent crer un supertype d'objet ; grce elles, nous utiliserons des objets de type :  EspritCombatif qui prsentent une mthode combat() ;  Soin qui prsentent une mthode soigne() ;  Deplacement qui prsentent une mthode deplace(). Dans notre classe Personnage, nous avons ajout une instance de chaque type de comportement, vous avez d les remarquer : il y a ces attributs dans notre schma ! Nous allons dvelopper un comportement par dfaut pour chacun d'entre eux et aecter cet objet dans notre superclasse. Les classes lles, elles, comprendront des instances direntes correspondant leurs besoins.

Du coup, que fait-on des mthodes de la superclasse Personnage ?


Nous les gardons, mais plutt que de rednir ces dernires, la superclasse va invoquer la mthode de comportement de chaque objet. Ainsi, nous n'avons plus rednir ou 150

LE PATTERN STRATEGY modier nos classes ! La seule chose qu'il nous reste faire, c'est d'aecter une instance de comportement nos objets. Vous comprendrez mieux avec un exemple. Voici quelques implmentations de comportements.  Exemple du pattern Strategy Code web : 292297 

Implmentations de l'interface EspritCombatif


pkge omFsdzFomportementY puli lss ifiste implements ispritgomtif { puli void omt@A { ystemFoutFprintln@4te ne omts ps 34AY } } pkge omFsdzFomportementY puli lss gomtistolet implements ispritgomtif{ puli void omt@A { ystemFoutFprintln@4te omts u pitolet 34AY } } pkge omFsdzFomportementY puli lss gomtgouteu implements ispritgomtif { puli void omt@A { ystemFoutFprintln@4te me ts u outeu 34AY } }

Implmentations de l'interface Deplacement


pkge omFsdzFomportementY puli lss wrher implements heplement { puli void depler@A { ystemFoutFprintln@4te me dple en mrhntF4AY } } pkge omFsdzFomportementY puli lss gourir implements heplement { puli void depler@A {

151

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES


ystemFoutFprintln@4te me dple en ourntF4AY

Implmentations de l'interface Soin


pkge omFsdzFomportementY puli lss remieroin implements oin { puli void soigne@A { ystemFoutFprintln@4te donne les premiers soinsF4AY } } pkge omFsdzFomportementY puli lss ypertion implements oin { puli void soigne@A { ystemFoutFprintln@4te prtique des oprtions 34AY } } pkge omFsdzFomportementY puli lss euunoin implements oin { puli void soigne@A { ystemFoutFprintln@4te ne donne egx soin 34AY } }

Voici ce que vous devriez avoir dans votre nouveau package (gure 13.13).

Figure

13.13  Package des comportements

152

LE PATTERN STRATEGY Maintenant que nous avons dni des objets de comportements, nous allons pouvoir remanier notre classe Personnage. Ajoutons les variables d'instance, les mutateurs et les constructeurs permettant d'initialiser nos objets :
import omFsdzFomportementFBY puli strt lss ersonnge { GGxos instnes de omportement proteted ispritgomtif espritgomtif a new ifiste@AY proteted oin soin a new euunoin@AY proteted heplement deplement a new wrher@AY GGgonstruteur pr dfut puli ersonnge@A{} GGgonstruteur ve prmtres puli ersonnge@ispritgomtif espritgomtifD oin soinD heplement deplementA { thisFespritgomtif a espritgomtifY thisFsoin a soinY thisFdeplement a deplementY } GGwthode de dplement de personnge puli void sehepler@A{ GGyn utilise les ojets de dplement de fon polymorphe deplementFdepler@AY } GG wthode que les omttnts utilisent puli void omttre@A{ GGyn utilise les ojets de dplement de fon polymorphe espritgomtifFomt@AY } GGwthode de soin puli void soigner@A{ GGyn utilise les ojets de dplement de fon polymorphe soinFsoigne@AY } GGedfinit le omportement u omt puli void setispritgomtif@ispritgomtif espritgomtifA { thisFespritgomtif a espritgomtifY } GGedfinit le omportement de oin puli void setoin@oin soinA { thisFsoin a soinY } GGedfinit le omportement de dplement puli void setheplement@heplement deplementA { thisFdeplement a deplementY }

153

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES


}

Que de changements depuis le dbut ! Maintenant, nous n'utilisons plus de mthodes dnies dans notre hirarchie de classes, mais des implmentations concrtes d'interfaces ! Les mthodes que nos objets appellent utilisent chacune un objet de comportement. Nous pouvons donc dnir des guerriers, des civils, des mdecins. . . tous personnalisables, puisqu'il sut de modier l'instance de leur comportement pour que ceux-ci changent instantanment. La preuve par l'exemple. Je ne vais pas vous donner les codes de toutes les classes. . . En voici seulement quelquesunes.

Guerrier.java
import omFsdzFomportementFBY puli lss querrier extends ersonnge { puli querrier@A{ thisFespritgomtif a new gomtistolet@AY } puli querrier@ispritgomtif espritD oin soinD heplement depA { super@espritD soinD depAY } }

Civil.java
import omFsdzFomportementFBY puli lss givil extends ersonnge{ puli givil@A {} puli givil@ispritgomtif espritD oin soinD heplement depA { super@espritD soinD depAY }

Medecin.java
import omFsdzFomportementFBY puli lss wedein extends ersonnge{ puli wedein@A { thisFsoin a new remieroin@AY } puli wedein@ispritgomtif espritD oin soinD heplement depA { super@espritD soinD depAY

154

LE PATTERN STRATEGY
}

Maintenant, voici un exemple d'utilisation :


lss est{ puli stti void min@tring rgsA { ersonnge ters a {new querrier@AD new givil@AD new wedein@A}Y for@int i a HY i ` tersFlengthY iCCA{ ystemFoutFprintln@4nsnstne de 4 C tersiFgetglss@AFgetxme@AAY ystemFoutFprintln@4BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB4AY tersiFomttre@AY tersiFsehepler@AY tersiFsoigner@AY }

Le rsultat de ce code nous donne la gure 13.14.

Figure

13.14  Test du pattern strategy

Vous pouvez voir que nos personnages ont tous un comportement par dfaut qui leur convient bien ! Nous avons spci, dans le cas o cela s'avre ncessaire, le comportement par dfaut d'un personnage dans son constructeur par dfaut :  le guerrier se bat avec un pistolet ;  le mdecin soigne. 155

CHAPITRE 13. LES CLASSES ABSTRAITES ET LES INTERFACES Voyons maintenant comment indiquer nos personnages de faire autre chose. . . Eh oui, la faon dont nous avons arrang tout cela va nous permettre de changer dynamiquement le comportement de chaque Personnage. Que diriez-vous de faire faire une petite opration chirurgicale notre objet Guerrier ? Pour ce faire, vous pouvez rednir son comportement de soin avec son mutateur prsent dans la superclasse en lui passant une implmentation correspondante !
import omFsdzFomportementFBY lss est{ puli stti void min@tring rgsA { ersonnge pers a new querrier@AY persiFsoigner@AY persiFsetoin@new ypertion@AAY persiFsoigner@AY } }

En testant ce code, vous constaterez que le comportement de soin de notre objet a chang dynamiquement sans que nous ayons besoin de changer la moindre ligne de son code source ! Le plus beau dans le fait de travailler comme cela, c'est qu'il est tout fait possible d'instancier des objets Guerrier avec des comportements dirents.

En rsum
              Une classe est dnie comme abstraite avec le mot cl abstract. Les classes abstraites sont utiliser lorsqu'une classe mre ne doit pas tre instancie. Une classe abstraite ne peut donc pas tre instancie. Une classe abstraite n'est pas oblige de contenir de mthode abstraite. Si une classe contient une mthode abstraite, cette classe doit alors tre dclare abstraite. Une mthode abstraite n'a pas de corps. Une interface est une classe 100 % abstraite. Aucune mthode d'une interface n'a de corps. Une interface sert dnir un supertype et utiliser le polymorphisme. Une interface s'implmente dans une classe en utilisant le mot cl implements. Vous pouvez implmenter autant d'interfaces que vous voulez dans vos classes. Vous devez rednir toutes les mthodes de l'interface (ou des interfaces) dans votre classe. Le pattern strategy vous permet de rendre une hirarchie de classes plus souple. Prfrez encapsuler des comportements plutt que de les mettre d'oce dans l'objet concern.

156

Chapitre

14
Dicult :

Les exceptions

oici encore une notion trs importante en programmation. Une exception est une erreur se produisant dans un programme qui conduit le plus souvent l'arrt de celui-ci. Il vous est srement dj arriv d'obtenir un gros message ach en rouge dans la console d'Eclipse : eh bien, cela a t gnr par une exception. . . qui n'a pas t capture. Le fait de grer les exceptions s'appelle aussi la capture d'exception ! Le principe consiste reprer un morceau de code (par exemple, une division par zro) qui pourrait gnrer une exception, de capturer l'exception correspondante et enn de traiter celle-ci, c'est--dire d'acher un message personnalis et de continuer l'excution. Bon, vous voyez maintenant ce que nous allons aborder dans ce chapitre. . . Donc, allons-y !

157

CHAPITRE 14. LES EXCEPTIONS

Le bloc try{...} catch{...}


Pour vous faire comprendre le principe des exceptions, je dois tout d'abord vous informer que Java contient une classe nomme Exception dans laquelle sont rpertoris dirents cas d'erreur. La division par zro dont je vous parlais plus haut en fait partie ! Si vous crez un nouveau projet avec seulement la classe main et y mettez le code suivant :
int j a PHD i a HY ystemFoutFprintln@jGiAY ystemFoutFprintln@4ouou toi 34AY

. . . vous verrez apparatre un joli message d'erreur Java (en rouge) comme celui de la gure 14.1.

Figure

14.1  ArithmeticException

Mais surtout, vous devez avoir constat que lorsque l'exception a t leve, le programme s'est arrt ! D'aprs le message ach dans la console, le nom de l'exception qui a t dclenche est ArithmeticException. Nous savons donc maintenant qu'une division par zro est une ArithmeticException. Nous allons pouvoir la capturer, avec un bloc try{...}catch{...}, puis raliser un traitement en consquence. Ce que je vous propose maintenant, c'est d'acher un message personnalis lors d'une division par 0. Pour ce faire, tapez le code suivant dans votre main :
puli stti void min@tring rgsA { int j a PHD i a HY try { ystemFoutFprintln@jGiAY } th @erithmetiixeption eA { ystemFoutFprintln@4hivision pr zro 34AY } ystemFoutFprintln@4ouou toi 34AY

En excutant ce code, vous obtiendrez le rsultat consultable sur la gure 14.2. Voyons un peu ce qui se passe.  Nous initialisons deux variables de type int, l'une 0 et l'autre un nombre quelconque. 158

LE BLOC TRY{...} CATCH{...}

Figure

14.2  Capture d'exception

 Nous isolons le code susceptible de lever une exception : System.out.println(j/i);.  Une exception de type ArithmeticException est leve lorsque le programme atteint cette ligne.  Notre bloc catch contient justement un objet de type ArithmeticException en paramtre. Nous l'avons appel e.  L'exception tant capture, l'instruction du bloc catch s'excute !  Notre message d'erreur personnalis s'ache alors l'cran. Vous vous demandez srement quoi sert le paramtre de la clause catch. Il permet de connatre le type d'exception qui doit tre captur. Et l'objet  ici, e  peut servir prciser notre message grce l'appel de la mthode getMessage(). Faites nouveau ce test, en remplaant l'instruction du catch par celle-ci :
ystemFoutFprintln@4hivision pr zro 34 C eFgetwessge@AAY

Vous verrez que la fonction getMessage() de notre objet ArithmeticException nous prcise la nature de l'erreur. Je vous disais aussi que le principe de capture d'exception permettait de ne pas interrompre l'excution du programme. En eet, lorsque nous capturons une exception, le code prsent dans le bloc catch(){...} est excut, mais le programme suit son cours ! Avant de voir comment crer nos propres exceptions, sachez que le bloc permettant de capturer ces dernires ore une fonctionnalit importante. En fait, vous avez sans doute compris que lorsqu'une ligne de code lve une exception, l'instruction dans le bloc try est interrompue et le programme se rend dans le bloc catch correspondant l'exception leve. Prenons un cas de gure trs simple : imaginons que vous souhaitez eectuer une action, qu'une exception soit leve ou non 1 . Java vous permet d'utiliser une clause via le mot cl finally. Voyons ce que donne ce code :
puli stti void min@tring rgsA{ try { ystemFoutFprintln@4 ab4 C @IGHAAY } th @glssgstixeption eA { eFprinttkre@AY } finlly{
ci. 1. Nous verrons lorsque nous travaillerons avec les chiers qu'il faut systmatiquement fermer ceux-

159

CHAPITRE 14. LES EXCEPTIONS


ystemFoutFprintln@4tion fite systmtiquement4AY

Lorsque vous l'excutez, vous pouvez constater que, mme si nous tentons d'intercepter une ArithmeticException 2 , grce la clause finally, un morceau de code est excut quoi qu'il arrive. Cela est surtout utilis lorsque vous devez vous assurer d'avoir ferm un chier, clos votre connexion une base de donnes ou un socket 3 . Maintenant que nous avons vu cela, nous pouvons aller un peu plus loin dans la gestion de nos exceptions.

Les exceptions personnalises


Nous allons perfectionner un peu la gestion de nos objets Ville et Capitale. . . Je vous propose de mettre en uvre une exception de notre cru an d'interdire l'instanciation d'un objet Ville ou Capitale prsentant un nombre ngatif d'habitants. La procdure pour faire ce tour de force est un peu particulire. En eet, nous devons : 1. crer une classe hritant de la classe Exception : NombreHabitantException 4 ; 2. renvoyer l'exception leve notre classe NombreHabitantException ; 3. ensuite, grer celle-ci dans notre classe NombreHabitantException. Pour faire tout cela, je vais encore vous apprendre deux mots cls.  throws : ce mot cl permet de signaler la JVM qu'un morceau de code, une mthode, une classe. . . est potentiellement dangereux et qu'il faut utiliser un bloc try{...}catch{...}. Il est suivi du nom de la classe qui va grer l'exception.  throw : celui-ci permet tout simplement de lever une exception manuellement en instanciant un objet de type Exception (ou un objet hrit). Dans l'exemple de notre ArithmeticException, il y a quelque part dans les mandres de Java un throw new ArithmeticException(). Pour mettre en pratique ce systme, commenons par crer une classe qui va grer nos exceptions. Celle-ci, je vous le rappelle, doit hriter d'Exception :
lss xomreritntixeption extends ixeption{ puli xomreritntixeption@A{ ystemFoutFprintln@4ous essyez d9instnier une lsse ille ve un nomre d9hitnts ngtif 34AY } }

Reprenez votre projet avec vos classes Ville et Capitale et crez ensuite une classe NombreHabitantException, comme je viens de le faire. Maintenant, c'est dans le
2. Celle-ci se dclenche lors d'un problme de cast. 3. Une connexion rseau. 4. Par convention, les exceptions ont un nom se terminant par Exception.

160

LES EXCEPTIONS PERSONNALISES constructeur de nos objets que nous allons ajouter une condition qui, si elle est remplie, lvera une exception de type NombreHabitantException. En gros, nous devons dire notre constructeur de Ville :  si l'utilisateur cre une instance de Ville avec un nombre d'habitants ngatif, crer un objet de type NombreHabitantException . Voil quoi ressemble le constructeur de notre objet Ville prsent :
puli ille@tring pxomD int pxreD tring pysA throws xomreritntixeption { if@pxre ` HA throw new xomreritntixeption@AY else { nresnstneCCY nresnstnefisCCY nomille a pxomY nomys a pysY nreritnt a pxreY thisFsetgtegorie@AY

seigne sur le type de l'erreur en question. Elle indique aussi la JVM que le constructeur de notre objet Ville est potentiellement dangereux et qu'il faudra grer les exceptions possibles. Si la condition if(nbre < 0) est remplie, throw new NombreHabitantException(); instancie la classe NombreHabitantException. Par consquent, si un nombre d'habitants est ngatif, l'exception est leve. Maintenant que vous avez apport cette petite modication, retournez dans votre classe main, eacez son contenu, puis crez un objet Ville de votre choix. Vous devez tomber sur une erreur persistante (gure 14.3) ; c'est tout fait normal et d l'instruction throws.

throws NombreHabitantException nous indique que si une erreur est capture, celle-ci sera traite en tant qu'objet de la classe NombreHabitantException, ce qui nous ren-

Figure

14.3  Exception non gre

Cela signie qu' partir de maintenant, vu les changements dans le constructeur, il 161

CHAPITRE 14. LES EXCEPTIONS vous faudra grer les exceptions qui pourraient survenir dans cette instruction avec un bloc try{} catch{}. Ainsi, pour que l'erreur disparaisse, il nous faut entourer notre instanciation avec un bloc try{...}catch{...} (gure 14.4).

Figure

14.4  Correction du bug

Vous pouvez constater que l'erreur a disparu, que notre code peut tre compil et qu'il s'excute correctement. Attention, il faut que vous soyez prpars une chose : le code que j'ai utilis dans la gure 14.4 fonctionne trs bien, mais il y a un autre risque, l'instance de mon objet Ville a t dclare dans le bloc try{...}catch{...} et cela peut causer beaucoup de problmes. Ce code :
puli stti void min@tring rgsA { try { ille v a new ille@4ennes4D IPHHHD 4prne4AY } th @xomreritntixeption eA { } } ystemFoutFprintln@vFtotring@AAY

. . . ne fonctionnera pas, tout simplement parce que la dclaration de l'objet Ville est faite dans un sous-bloc d'instructions, celui du bloc try{...}. Et rappelez-vous : une variable dclare dans un bloc d'instructions n'existe que dans celui-ci ! 162

LES EXCEPTIONS PERSONNALISES Ici, la variable v n'existe pas en dehors de l'instruction try{...}. Pour pallier ce problme, il nous sut de dclarer notre objet en dehors du bloc try{...} et de l'instancier l'intrieur :
puli stti void min@tring rgsA { ille v a nullY try { v a new ille@4ennes4D IPHHHD 4prne4AY } th @xomreritntixeption eA { } } ystemFoutFprintln@vFtotring@AAY

Mais que se passera-t-il si nous dclarons une Ville avec un nombre d'habitants ngatif pour tester notre exception ? En remplaant  12000  par  -12000  dans l'instanciation de notre objet. . . C'est simple : en plus d'une exception leve pour le nombre d'habitants ngatif, vous obtiendrez aussi une NullPointerException. Voyons ce qu'il s'est pass.  Nous avons bien dclar notre objet en dehors du bloc d'instructions.  Au moment d'instancier celui-ci, une exception est leve et l'instanciation choue !  La clause catch{} est excute : un objet NombreHabitantException est instanci.  Lorsque nous arrivons sur l'instruction  System.out.println(v.toString()); , notre objet est null !  Une NullPointerException est donc leve ! Ce qui signie que si l'instanciation choue dans notre bloc try{}, le programme plante ! Pour rsoudre ce problme, on peut utiliser une simple clause finally avec, l'intrieur, l'instanciation d'un objet Ville par dfaut si celui-ci est null :
puli stti void min@tring rgsA { ille v a nullY try { v a new ille@4ennes4D IPHHHD 4prne4AY } th @xomreritntixeption eA { } finlly{ if@v aa nullA v a new ille@AY } ystemFoutFprintln@vFtotring@AAY }

Pas besoin de capturer une exception sur l'instanciation de notre objet ici : le code n'est considr comme dangereux que sur le constructeur avec paramtres. Maintenant que nous avons vu la cration d'une exception, il serait de bon ton de pouvoir rcolter plus de renseignements la concernant. Par exemple, il serait peut-tre intressant de racher le nombre d'habitants que l'objet a reu. 163

CHAPITRE 14. LES EXCEPTIONS Pour ce faire, nous n'avons qu' crer un deuxime constructeur dans notre classe NombreHabitantException qui prend un nombre d'habitants en paramtre :
puli xomreritntixeption@int nreA { ystemFoutFprintln@4snstnition ve un nomre d9hitnts ngtifF4AY ystemFoutFprintln@4t ab 4 C nreAY }

Il sut maintenant de modier le constructeur de la classe Ville en consquence :


puli ille@tring pxomD int pxreD tring pysA throws xomreritntixeption { if@pxre ` HA throw new xomreritntixeption@pxreAY else { GGve ode est identique prdemment } }

Et si vous excutez le mme code que prcdemment, vous pourrez voir le nouveau message de notre exception s'acher. Ce n'est pas mal, avouez-le ! Sachez galement que l'objet pass en paramtre de la clause catch a des mthodes hrites de la classe Exception : vous pouvez les utiliser si vous le voulez et surtout, si vous en avez l'utilit. Nous utiliserons certaines de ces mthodes dans les prochains chapitres. Je vais vous faire peur : ici, nous avons captur une exception, mais nous pouvons en capturer plusieurs. . . Pour nir, je vous propose de tlcharger tous ces morceaux de codes que nous venons de voir ensemble.  Copier les codes Code web : 842950 

La gestion de plusieurs exceptions


Bien entendu, ceci est valable pour toutes sortes d'exceptions, qu'elles soient personnalises ou inhrentes Java ! Supposons que nous voulons lever une exception si le nom de la ville fait moins de 3 caractres. Nous allons rpter les premires tapes vues prcdemment, c'est--dire crer une classe NomVilleException :
puli lss xomilleixeption extends ixeption { puli xomilleixeption@tring messgeA{ super@messgeAY

164

LA GESTION DE PLUSIEURS EXCEPTIONS


}

Vous avez remarqu que nous avons utilis super. Avec cette rednition, nous pourrons acher notre message d'erreur en utilisant la mthode getMessage(). Voyez plutt. Ajoutez une condition dans le constructeur Ville :
puli ille@tring pxomD int pxreD tring pysA throws xomreritntixeptionD xomilleixeption { if@pxre ` HA throw new xomreritntixeption@pxreAY if@pxomFlength@A ` QA throw new xomilleixeption@4le nom de l ville est infrieur Q rtres 3 nom a 4 C pxomAY else { nresnstneCCY nresnstnefisCCY nomille a pxomY nomys a pysY nreritnt a pxreY thisFsetgtegorie@AY

Vous remarquez que les direntes erreurs dans l'instruction throws sont spares par une virgule. Nous sommes maintenant pars pour la capture de deux exceptions personnalises. Regardez comment on gre deux exceptions sur une instruction :
ille v a nullY try { v a new ille@4e4D IPHHHD 4prne4AY } GGqestion de l9exeption sur le nomre d9hitnts th @xomreritntixeption eA { eFprinttkre@AY } GGqestion de l9exeption sur le nom de l ville th@xomilleixeption ePA{ ystemFoutFprintln@ePFgetwessge@AAY } finlly{ if@v aa nullA v a new ille@AY } ystemFoutFprintln@vFtotring@AAY

165

CHAPITRE 14. LES EXCEPTIONS Constatez qu'un deuxime bloc catch{} s'est gliss. . . Eh bien, c'est comme cela que nous grerons plusieurs exceptions ! Si vous mettez un nom de ville de moins de 3 caractres et un nombre d'habitants ngatif, c'est l'exception du nombre d'habitants qui sera leve en premier, et pour cause : il s'agit de la premire condition dans notre constructeur. Lorsque plusieurs exceptions sont gres par une portion de code, pensez bien mettre les blocs catch dans un ordre pertinent.

En rsum
 Lorsqu'un vnement que la JVM ne sait pas grer apparat, une exception est leve (exemple : division par zro). Une exception correspond donc une erreur.  La superclasse qui gre les exceptions s'appelle Exception.  Vous pouvez crer une classe d'exception personnalise : faites-lui hriter de la classe Exception.  L'instruction qui permet de capturer des exceptions est le bloc try{} catch{}.  Si une exception est leve dans le bloc try, les instructions gurant dans le bloc catch seront excutes pour autant que celui-ci capture la bonne exception leve.  Vous pouvez ajouter autant de blocs catch que vous le voulez la suite d'un bloc try, mais respectez l'ordre : du plus pertinent au moins pertinent.  Dans une classe objet, vous pouvez prvenir la JVM qu'une mthode est dite  risque  grce au mot cl throws.  Vous pouvez dnir plusieurs risques d'exceptions sur une mme mthode. Il sut de sparer les dclarations par une virgule.  Dans cette mthode, vous pouvez dnir les conditions d'instanciation d'une exception et lancer cette dernire grce au mot cl throw suivi de l'instanciation.  Une instanciation lance par le biais de l'instruction throw doit tre dclare avec throws au pralable !

166

Chapitre

15
Dicult :

Les ux d'entre/sortie

ne entre/sortie en Java consiste en un change de donnes entre le programme et une autre source, par exemple la mmoire, un chier, le programme lui-mme. . . Pour raliser cela, Java emploie ce qu'on appelle un stream (qui signie  ux ). Celui-ci joue le rle de mdiateur entre la source des donnes et sa destination. Nous allons voir que Java met notre disposition toute une panoplie d'objets permettant de communiquer de la sorte. Toute opration sur les entres/sorties doit suivre le schma suivant : ouverture, lecture, fermeture du ux. Je ne vous cache pas qu'il existe une foule d'objets qui ont chacun leur faon de travailler avec les ux. Sachez que Java a dcompos les objets traitant des ux en deux catgories :  les objets travaillant avec des ux d'entre (in), lecture de ux ;  les objets travaillant avec des ux de sortie (out), criture de ux.

167

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE

Utilisation de java.io
L'objet File
Avant de commencer, crez un chier avec l'extension que vous voulez pour le moment, et enregistrez-le la racine de votre projet Eclipse. Personnellement, je me suis fait un chier test.txt dont voici le contenu :
oii une ligne de testF oii une utre ligne de testF it omme je suis motivD en voii une troisime 3

Dans votre projet Eclipse, faites un clic droit sur le dossier de votre projet, puis New File. Vous pouvez nommer votre chier ainsi qu'y taper du texte ! Le nom du dossier contenant mon projet s'appelle  IO  et mon chier texte est cette adresse :  D :\Mes documents\Codage\SDZ\Java-SDZ\IO\test.txt . Nous allons maintenant voir ce dont l'objet File est capable. Vous remarquerez que cet objet est trs simple utiliser et que ses mthodes sont trs explicites.
GGkge importer fin d9utiliser l9ojet pile import jvFioFpileY puli lss win { puli stti void min@tring rgsA { GGgrtion de l9ojet pile pile f a new pile@4testFtxt4AY ystemFoutFprintln@4ghemin solu du fihier X 4 C fFgetesoluteth@AAY ystemFoutFprintln@4xom du fihier X 4 C fFgetxme@AAY ystemFoutFprintln@4istEe qu9il existe c 4 C fFexists@AAY ystemFoutFprintln@4istEe un rpertoire c 4 C fFishiretory@AAY ystemFoutFprintln@4istEe un fihier c 4 C fFispile@AAY ystemFoutFprintln@4effihge des leteurs l rine du g X 4AY for@pile file X fFlistoots@AA { ystemFoutFprintln@fileFgetesoluteth@AAY try { int i a IY GGyn prourt l liste des fihiers et rpertoires for@pile nom X fileFlistpiles@AA{ GG9il s9git d9un dossierD on joute un 4G4 ystemFoutFprint@4tt4 C @@nomFishiretory@AA c nomFgetxme@AC4G4 X nomFgetxme@AAAY if@@i7RA aa HA{ ystemFoutFprint@4n4AY } iCCY

168

UTILISATION DE JAVA.IO
ystemFoutFprintln@4n4AY } th @xullointerixeption eA { GGv9instrution peut gnrer une xullointerixeption GGs9il n9y ps de sousEfihier 3 }

Copier ce code Code web : 604161  Le rsultat est bluant (gure 15.1).

Figure

15.1  Test de l'objet File

Vous conviendrez que les mthodes de cet objet peuvent s'avrer trs utiles ! Nous venons d'en essayer quelques-unes et nous avons mme list les sous-chiers et sousdossiers de nos lecteurs la racine du PC. Vous pouvez aussi eacer le chier grce la mthode delete(), crer des rpertoires avec la mthode mkdir() 1 . . . Maintenant que vous en savez un peu plus sur cet objet, nous pouvons commencer travailler avec notre chier !

Les objets FileInputStream et FileOutputStream


C'est par le biais de ces objets que nous allons pouvoir :  lire dans un chier ;  crire dans un chier.
1. Le nom donn ce rpertoire ne pourra cependant pas contenir de point ( . ).

169

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE Ces classes hritent des classes abstraites InputStream et OutputStream, prsentes dans le package java.io. Comme vous l'avez sans doute devin, il existe une hirarchie de classes pour les traitements in et une autre pour les traitements out. Ne vous y trompez pas, les classes hritant d'InputStream sont destines la lecture et les classes hritant d'OutputStream se chargent de l'criture ! C'est bizarre, n'est-ce pas ? Vous auriez dit le contraire. . . Comme beaucoup de gens au dbut. Mais c'est uniquement parce que vous situez les ux par rapport vous, et non votre programme ! Lorsque ce dernier va lire des informations dans un chier, ce sont des informations qu'il reoit, et par consquent, elles s'apparentent une entre : in 2 . Au contraire, lorsqu'il va crire dans un chier 3 , par exemple, il va faire sortir des informations ; donc, pour lui, ce ux de donnes correspond une sortie : out. Nous allons enn commencer travailler avec notre chier. Le but est d'aller en lire le contenu et de le copier dans un autre, dont nous spcierons le nom dans notre programme, par le biais d'un programme Java. Ce code est assez compliqu, donc accrochez-vous vos claviers !
GGkges importer fin d9utiliser les ojets import jvFioFpileY import jvFioFpilesnputtremY import jvFioFpilexotpoundixeptionY import jvFioFpileyutputtremY import jvFioFsyixeptionY puli lss win { puli stti void min@tring rgsA { GGxous dlrons nos ojets en dehors du lo tryGth pilesnputtrem fis a nullY pileyutputtrem fos a nullY try { GGyn instnie nos ojets X GGfis v lire le fihier et GGfos v rire dns le nouveu 3 fis a new pilesnputtrem@new pile@4testFtxt4AAY fos a new pileyutputtrem@new pile@4testPFtxt4AAY GGyn re un tleu de yte GGpour indiquer le nomre de ytes GGlus hque tour de oule yte uf a new yteVY
2. Sachez tout de mme que lorsque vous tapez au clavier, cette action est considre comme un ux d'entre ! 3. Ou l'cran, souvenez-vous de System.out.println.

170

UTILISATION DE JAVA.IO
GGyn re une vrile de type int GGpour y ffeter le rsultt de l leture GGut EI qund 9est fini int n a HY GGnt que l9ffettion dns l vrile est possileD on oule GGvorsque l leture du fihier est termine GGl9ffettion n9est plus possile 3 GGyn sort don de l oule while@@n a fisFred@ufAA ba HA { GGyn rit dns notre deuxime fihier GGve l9ojet dqut fosFwrite@ufAY GGyn ffihe e qu9 lu notre oule GGu formt yte et u formt hr for@yte it X ufA ystemFoutFprint@4t4 C it C 4@4 C @hrAit C 4A4AY ystemFoutFprintln@44AY } ystemFoutFprintln@4gopie termine 34AY } th @pilexotpoundixeption eA { GGgette exeption est leve GGsi l9ojet pilesnputtrem ne trouve uun fihier eFprinttkre@AY } th @syixeption eA { GGgelleEi se produit lors d9une erreur GGd9riture ou de leture eFprinttkre@AY } finlly{ GGyn ferme nos flux de donnes dns un lo finlly GGpour s9ssurer que es instrutions seront exutes GGdns tous les s mme si une exeption est leve 3 try{ if@fis 3a nullA fisFlose@AY if@fos 3a nullA fosFlose@AY }th@syixeption eA{ eFprinttkre@AY } } }

Copier ce code Code web : 530777 

171

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE

Pour que l'objet FileInputStream fonctionne, le chier doit exister ! Sinon l'exception FileNotFoundException est leve. Par contre, si vous ouvrez un ux en criture (FileOutputStream) vers un chier inexistant, celui-ci sera cr automatiquement !
Notez bien les imports pour pouvoir utiliser ces objets. Mais comme vous le savez dj, vous pouvez taper votre code et faire ensuite  CTRL + SHIFT + O  pour que les imports soient automatiques. l'excution de ce code, vous pouvez voir que le chier test2.txt a bien t cr et qu'il contient exactement la mme chose que test.txt ! De plus, j'ai ajout dans la console les donnes que votre programme va utiliser (lecture et criture). La gure 15.2 reprsente le rsultat de ce code.

Figure

15.2  Copie de chier

Le bloc finally permet de s'assurer que nos objets ont bien ferm leurs liens avec leurs chiers respectifs, ceci an de permette Java de dtruire ces objets pour ainsi librer un peu de mmoire votre ordinateur.

En eet, les objets utilisent des ressources de votre ordinateur que Java ne peut pas librer de lui-mme, vous devez tre sr que la vanne est ferme ! Ainsi, mme si une exception est leve, le contenu du bloc finally sera excut et nos ressources seront libres. Par contre, pour allger la lecture, je ne mettrai plus ces blocs dans les codes venir mais pensez bien les mettre dans vos codes.
Les objets FileInputStream et FileOutputStream sont assez rudimentaires, car ils travaillent avec un nombre dtermin d'octets lire. Cela explique pourquoi ma condition de boucle tait si tordue. . . 172

UTILISATION DE JAVA.IO

Voici un rappel important : lorsque vous voyez des caractres dans un chier ou

sur votre cran, ils ne veulent pas dire grand-chose pour votre PC, car il ne comprend que le binaire (vous savez, les suites de 0 et de 1). Ainsi, an de pouvoir acher et travailler avec des caractres, un systme d'encodage (qui a d'ailleurs fort volu) a t mis au point. Sachez que chaque caractre que vous saisissez ou que vous lisez dans un chier correspond un code binaire, et ce code binaire correspond un code dcimal. Voyez la table de correspondance 4 .


Table de correspondance Code web : 277885 

Cependant, au dbut, seuls les caractres de a z, de A Z et les chires de 0 9 (les 127 premiers caractres de la table ci-dessus) taient cods (UNICODE 1), correspondant aux caractres se trouvant dans la langue anglaise. Mais ce codage s'est rapidement avr trop limit pour des langues comportant des caractres accentus (franais, espagnol. . .). Un jeu de codage de caractres tendu a t mis en place an de pallier ce problme. Chaque code binaire UNICODE 1 est cod sur 8 bits, soit 1 octet. Une variable de type byte, en Java, correspond en fait 1 octet et non 1 bit ! Les objets que nous venons d'utiliser emploient la premire version d'UNICODE 1 qui ne comprend pas les caractres accentus, c'est pourquoi ces caractres ont un code dcimal ngatif dans notre chier. Lorsque nous dnissons un tableau de byte 8 entres, cela signie que nous allons lire 8 octets la fois. Vous pouvez voir qu' chaque tour de boucle, notre tableau de byte contient huit valeurs correspondant chacune un code dcimal qui, lui, correspond un caractre 5 . Vous pouvez voir que les codes dcimaux ngatifs sont inconnus, car ils sont reprsents par des  ?  ; de plus, il y a des caractres invisibles 6 dans notre chier :  les espaces : SP pour SPace, code dcimal 32 ;  les sauts de lignes : LF pour Line Feed, code dcimal 13 ;  les retours chariot : CR pour Carriage Return, code dcimal 10. Vous voyez que les traitements des ux suivent une logique et une syntaxe prcises ! Lorsque nous avons copi notre chier, nous avons rcupr un certain nombre d'octets dans un ux entrant que nous avons pass un ux sortant. chaque tour de boucle, les donnes lues dans le chier source sont crites dans le chier dni comme copie. Il existe prsent des objets beaucoup plus faciles utiliser, mais qui travaillent nanmoins avec les deux objets que nous venons d'tudier. Ces objets font galement partie de la hirarchie cite prcdemment. . . Seulement, il existe une superclasse qui les dnit.
4. On parle de la table ASCII. 5. Valeur entre parenthses ct du code dcimal. 6. Les 32 premiers caractres de la table ASCII sont invisibles !

173

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE

Les objets FilterInputStream et FilterOutputStream


Ces deux classes sont en fait des classes abstraites. Elles dnissent un comportement global pour leurs classes lles qui, elles, permettent d'ajouter des fonctionnalits aux ux d'entre/sortie ! La gure 15.3 reprsente un diagramme de classes schmatisant leur hirarchie.

Figure

15.3  Hirarchie des classes du package java.io

Vous pouvez voir qu'il existe quatre classes lles hritant de FilterInputStream (de mme pour FilterOutputStream 7 ).  DataInputStream : ore la possibilit de lire directement des types primitifs (double, char, int) grce des mthodes comme readDouble(), readInt(). . .  BufferedInputStream : cette classe permet d'avoir un tampon disposition dans la lecture du ux. En gros, les donnes vont tout d'abord remplir le tampon, et ds que celui-ci est plein, le programme accde aux donnes.  PushbackInputStream : permet de remettre un octet dj lu dans le ux entrant.  LineNumberInputStream : cette classe ore la possibilit de rcuprer le numro de la ligne lue un instant T. Ces classes prennent en paramtre une instance drivant des classes InputStream(pour les classes hritant de FilterInputStream) ou de OutputStream (pour les classes hritant de FilterOutputStream). Puisque ces classes acceptent une instance de leur superclasse en paramtre, vous pouvez cumuler les ltres et obtenir des choses de ce genre :
7. Les classes drivant de FilterOutputStream ont les mmes fonctionnalits, mais en criture.

174

UTILISATION DE JAVA.IO
pilesnputtrem fis htsnputtrem dis fufferedsnputtrem GGyu en ondens X fufferedsnputtrem a new pilesnputtrem@new pile@4totoFtxt4AAY a new htsnputtrem@fisAY is a new fufferedsnputtrem@disAY is a new fufferredsnputtrem@ new htsnputtrem@ new pilesnputtrem@ new pile@4totoFtxt4AAAAY

An de vous rendre compte des amliorations apportes par ces classes, nous allons lire un norme chier texte (3,6 Mo) de faon conventionnelle avec l'objet vu prcdemment, puis grce un buer. Tlcharger le chier Code web : 588152  Rcuprez le chier compress grce un logiciel de compression/dcompression et remplacez le contenu de votre chier test.txt par le contenu de ce chier. Maintenant, voici un code qui permet de tester le temps d'excution de la lecture :
GGkges importer fin d9utiliser l9ojet pile import jvFioFfufferedsnputtremY import jvFioFhtsnputtremY import jvFioFpileY import jvFioFpilesnputtremY import jvFioFpilexotpoundixeptionY import jvFioFpileyutputtremY import jvFioFsyixeptionY puli lss win { puli stti void min@tring rgsA { GGxous dlrons nos ojets en dehors du lo tryGth pilesnputtrem fisY fufferedsnputtrem isY try { fis a new pilesnputtrem@new pile@4testFtxt4AAY is a new fufferedsnputtrem@new pilesnputtrem@new pile@4 testFtxt4AAAY yte uf a new yteVY GGyn rupre le temps du systme long strtime a ystemFurrentimewillis@AY GGsnutile d9effetuer des tritements dns notre oule while@fisFred@ufA 3a EIAY GGyn ffihe le temps d9exution ystemFoutFprintln@4emps de leture ve pilesnputtrem X 4 C @ystemFurrentimewillis@A E strtimeAAY GGyn rinitilise strtime a ystemFurrentimewillis@AY

175

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE


GGsnutile d9effetuer des tritements dns notre oule while@isFred@ufA 3a EIAY GGyn rffihe ystemFoutFprintln@4emps de leture ve fufferedsnputtrem X 4 C @ystemFurrentimewillis@A E strtimeAAY GGyn ferme nos flux de donnes fisFlose@AY isFlose@AY } th @pilexotpoundixeption eA { eFprinttkre@AY } th @syixeption eA { eFprinttkre@AY }

Et le rsultat (gure 15.4) est encore une fois bluant.

Figure

15.4  Comparatif de lecture avec et sans ltre

La dirence de temps est vraiment norme : 1,578 seconde pour la premire mthode et 0,094 seconde pour la deuxime ! Vous conviendrez que l'utilisation d'un buer permet une nette amlioration des performances de votre code. Faisons donc sans plus tarder le test avec l'criture :
GGkges importer fin d9utiliser l9ojet pile import jvFioFfufferedsnputtremY import jvFioFfufferedyutputtremY import jvFioFpileY import jvFioFpilesnputtremY import jvFioFpilexotpoundixeptionY import jvFioFpileyutputtremY import jvFioFsyixeptionY puli lss win { puli stti void min@tring rgsA { GGxous dlrons nos ojets en dehors du lo tryGth pilesnputtrem fisY pileyutputtrem fosY fufferedsnputtrem isY fufferedyutputtrem osY

176

UTILISATION DE JAVA.IO
try {

fis a new pilesnputtrem@new pile@4testFtxt4AAY fos a new pileyutputtrem@new pile@4testPFtxt4AAY is a new fufferedsnputtrem@new pilesnputtrem@new pile@4 testFtxt4AAAY os a new fufferedyutputtrem@new pileyutputtrem@new pile@4 testQFtxt4AAAY yte uf a new yteVY GGyn rupre le temps du systme long strtime a ystemFurrentimewillis@AY while@fisFred@ufA 3a EIA{ fosFwrite@ufAY } GGyn ffihe le temps d9exution ystemFoutFprintln@4emps de leture C riture ve pilesnputt rem et pileyutputtrem X 4 C @ystemFurrentimewillis@A E strtimeAAY GGyn rinitilise strtime a ystemFurrentimewillis@AY while@isFred@ufA 3a EIA{ osFwrite@ufAY } GGyn rffihe ystemFoutFprintln@4emps de leture C riture ve fufferedsn puttrem et fufferedyutputtrem X 4 C @ystemFurrentimewillis@A E strtimeAAY GGyn ferme nos flux de donnes fisFlose@AY isFlose@AY } th @pilexotpoundixeption eA { eFprinttkre@AY } th @syixeption eA { eFprinttkre@AY }

L, la dirence est encore plus nette (gure 15.5). Si avec a, vous n'tes pas convaincus de l'utilit des buers. . . Je ne vais pas passer en revue tous les objets cits un peu plus haut, mais vu que vous risquez d'avoir besoin des objets Data(Input/Output)Stream, nous allons les aborder rapidement, puisqu'ils s'utilisent comme les objets BufferedInputStream. Je vous ai dit plus haut que ceux-ci ont des mthodes de lecture pour chaque type primitif : il faut cependant que le chier soit gnr par le biais d'un DataOutputStream pour que 177

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE

Figure

15.5  Comparatif d'criture avec et sans ltre

les mthodes fonctionnent correctement. Nous allons donc crer un chier de toutes pices pour le lire par la suite.
GGkges importer fin d9utiliser l9ojet pile import jvFioFfufferedsnputtremY import jvFioFfufferedyutputtremY import jvFioFhtsnputtremY import jvFioFhtyutputtremY import jvFioFpileY import jvFioFpilesnputtremY import jvFioFpilexotpoundixeptionY import jvFioFpileyutputtremY import jvFioFsyixeptionY puli lss win { puli stti void min@tring rgsA { GGxous dlrons nos ojets en dehors du lo tryGth htsnputtrem disY htyutputtrem dosY try { dos a new htyutputtrem@ new fufferedyutputtrem@ new pileyutputtrem@ new pile@4sdzFtxt4AAAAY GGxous llons rire hque type primitif dosFwritefoolen@trueAY dosFwritefyte@IHHAY dosFwriteghr@9g9AY dosFwritehoule@IPFHSAY dosFwriteplot@IHHFSPfAY dosFwritesnt@IHPRAY dosFwritevong@IPQRSTUVWTSRQPIvAY dosFwritehort@PAY dosFlose@AY GGyn rupre mintennt les donnes 3 dis a new htsnputtrem@ new fufferedsnputtrem@ new pilesnputtrem@ new pile@4sdzFtxt4AAAAY

178

UTILISATION DE JAVA.IO
ystemFoutFprintln@disFredfoolen@AAY ystemFoutFprintln@disFredfyte@AAY ystemFoutFprintln@disFredghr@AAY ystemFoutFprintln@disFredhoule@AAY ystemFoutFprintln@disFredplot@AAY ystemFoutFprintln@disFredsnt@AAY ystemFoutFprintln@disFredvong@AAY ystemFoutFprintln@disFredhort@AAY } th @pilexotpoundixeption eA { eFprinttkre@AY } th @syixeption eA { eFprinttkre@AY }

La gure 15.6 correspond au rsultat de ce code.

Figure

15.6  Test avec les DataInputStream  DataOutputStream

Le code est simple, clair et concis. . . Vous avez pu constater que ce type d'objet ne manque pas de fonctionnalits ! Jusqu'ici, nous ne travaillions qu'avec des types primitifs, mais il est galement possible de travailler avec des objets !

Les objets ObjectInputStream et ObjectOutputStream


Vous devez savoir que lorsqu'on veut crire des objets dans des chiers, on appelle a la srialisation : c'est le nom que porte l'action de sauvegarder des objets ! Cela fait quelque temps dj que vous utilisez des objets et, j'en suis sr, vous avez dj souhait que certains d'entre eux soient rutilisables. . . Le moment est venu de sauver vos objets d'une mort certaine ! Pour commencer, nous allons voir comment srialiser un objet de notre composition. Voici la classe avec laquelle nous allons travailler :
GGkge importer import jvFioFerilizleY puli lss qme implements erilizle{ privte tring nomD styleY

179

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE


privte doule prixY puli qme@tring nomD tring styleD doule prixA { thisFnom a nomY thisFstyle a styleY thisFprix a prixY } puli tring totring@A{ return 4xom du jeu X 4 C thisFnom C 4ntyle de jeu X 4 C thisFstyle C 4nrix du jeu X 4 C thisFprix C 4n4Y }

Qu'est-ce que c'est que cette interface ? Tu n'as mme pas implment de mthode !
En fait, cette interface n'a pas de mthode rednir : l'interface Serializable est ce qu'on appelle une interface marqueur ! Rien qu'en implmentant cette interface dans un objet, Java sait que cet objet peut tre srialis ; et j'irai mme plus loin : si vous n'implmentez pas cette interface dans vos objets, ceux-ci ne pourront pas tre srialiss ! En revanche, si une superclasse implmente l'interface Serializable, ses enfants seront considrs comme srialisables. Voici ce que nous allons faire :  nous allons crer deux ou trois objets Game ;  nous allons les srialiser dans un chier de notre choix ;  nous allons ensuite les dsrialiser an de pouvoir les rutiliser. Vous avez srement dj senti comment vous allez vous servir de ces objets, mais travaillons tout de mme sur l'exemple que voici :
GGkges importer fin d9utiliser l9ojet pile import jvFioFfufferedsnputtremY import jvFioFfufferedyutputtremY import jvFioFhtsnputtremY import jvFioFhtyutputtremY import jvFioFpileY import jvFioFpilesnputtremY import jvFioFpilexotpoundixeptionY import jvFioFpileyutputtremY import jvFioFsyixeptionY import jvFioFyjetsnputtremY import jvFioFyjetyutputtremY puli lss win { puli stti void min@tring rgsA {

180

UTILISATION DE JAVA.IO
GGxous dlrons nos ojets en dehors du lo tryGth yjetsnputtrem oisY yjetyutputtrem oosY try { oos a new yjetyutputtrem@ new fufferedyutputtrem@ new pileyutputtrem@ new pile@4gmeFtxt4AAAAY GGxous llons rire hque ojet qme dns le fihier oosFwriteyjet@new qme@4essssin greed4D 4eventure4D RSFTWAAY oosFwriteyjet@new qme@4om ider4D 4lteforme4D PQFRSAAY oosFwriteyjet@new qme@4etris4D 4trtgie4D PFSHAAY GGxe ps oulier de fermer le flux 3 oosFlose@AY GGyn rupre mintennt les donnes 3 ois a new yjetsnputtrem@ new fufferedsnputtrem@ new pilesnputtrem@ new pile@4gmeFtxt4AAAAY try { ystemFoutFprintln@4effihge des jeux X4AY ystemFoutFprintln@4BBBBBBBBBBBBBBBBBBBBBBBBBn4AY ystemFoutFprintln@@@qmeAoisFredyjet@AAFtotring@AAY ystemFoutFprintln@@@qmeAoisFredyjet@AAFtotring@AAY ystemFoutFprintln@@@qmeAoisFredyjet@AAFtotring@AAY } th @glssxotpoundixeption eA { eFprinttkre@AY } oisFlose@AY } th @pilexotpoundixeption eA { eFprinttkre@AY } th @syixeption eA { eFprinttkre@AY }

La dsrialisation d'un objet peut engendrer une ClassNotFoundException, pensez donc la capturer !
Et voyez le rsultat en gure 15.7. Ce qu'il se passe est simple : les donnes de vos objets sont enregistres dans le chier. 181

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE

Figure

15.7  Srialisation  dsrialisation

Mais que se passerait-il si notre objet Game avait un autre objet de votre composition en son sein ? Voyons a tout de suite. Crez la classe Notice comme suit :
puli lss xotie { privte tring lngue Y puli xotie@A{ thisFlngue a 4prnis4Y } puli xotie@tring lngA{ thisFlngue a lngY } puli tring totring@A { return 4t vngue de l notie X 4 C thisFlngue C 4n4Y } }

Nous allons maintenant implmenter une notice par dfaut dans notre objet Game. Voici notre classe modie :
import jvFioFerilizleY puli lss qme implements erilizle{ privte tring nomD styleY privte doule prixY privte xotie notieY puli qme@tring nomD tring styleD doule prixA { thisFnom a nomY thisFstyle a styleY thisFprix a prixY thisFnotie a new xotie@AY }

182

UTILISATION DE JAVA.IO
puli tring totring@A{ return 4xom du jeu X 4 C thisFnom C 4ntyle de jeu X 4 C thisFstyle C 4nrix du jeu X 4 C thisFprix C 4n4Y }

Ressayez votre code sauvegardant vos objets Game. La gure 15.8 nous montre le rsultat obtenu.

Figure

15.8  Erreur de srialisation

Eh non, votre code ne compile plus ! Il y a une bonne raison cela : votre objet Notice n'est pas srialisable, une erreur de compilation est donc leve. Maintenant, deux choix s'orent vous :  soit vous faites en sorte de rendre votre objet srialisable ;  soit vous spciez dans votre classe Game que la variable notice n'a pas tre srialise. Pour la premire option, c'est simple, il sut d'implmenter l'interface srialisable dans notre classe Notice. Pour la seconde, il sut de dclarer votre variable : transient. Comme ceci :
import jvFioFerilizleY puli lss qme implements erilizle{ privte tring nomD styleY privte doule prixY GGwintenntD ette vrile ne ser ps srilise GGille ser tout onnement ignore 3 privte trnsient xotie notieY puli qme@tring nomD tring styleD doule prixA { thisFnom a nomY thisFstyle a styleY thisFprix a prixY

183

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE


thisFnotie a new xotie@AY

puli tring totring@A{ return 4xom du jeu X 4 C thisFnom C 4ntyle de jeu X 4 C thisFstyle C 4nrix du jeu X 4 C thisFprix C 4n4Y }

Vous aurez sans doute remarqu que nous n'utilisons pas la variable notice dans la mthode toString() de notre objet Game. Si vous faites ceci, que vous srialisez puis dsrialisez vos objets, la machine virtuelle vous renverra l'exception NullPointerException l'invocation de ladite mthode. Eh oui ! L'objet Notice est ignor : il n'existe donc pas !

Les objets CharArray(Writer/Reader) et String(Writer/Reader)


Nous allons utiliser des objets :  CharArray(Writer/Reader) ;  String(Writer/Reader). Ces deux types jouent quasiment le mme rle. De plus, ils ont les mmes mthodes que leur classe mre. Ces deux objets n'ajoutent donc aucune nouvelle fonctionnalit leur objet mre. Leur principale fonction est de permettre d'crire un ux de caractres dans un buer adaptatif : un emplacement en mmoire qui peut changer de taille selon les besoins 8 . Commenons par un exemple comment des objets CharArray(Writer/Reader) :
GGkges importer fin d9utiliser l9ojet pile import jvFioFghrerryederY import jvFioFghrerryriterY import jvFioFsyixeptionY puli lss win { puli stti void min@tring rgsA { ghrerryriter w a new ghrerryriter@AY ghrerryeder rY try { wFwrite@4gouou les ros4AY GGeppel l mthode totring
8. Nous n'en avons pas parl dans le chapitre prcdent an de ne pas l'alourdir, mais il existe des classes remplissant le mme rle que ces classes-ci : ByteArray(Input/Output)Stream.

184

UTILISATION DE JAVA.IO
GGde notre ojet de mnire tite ystemFoutFprintln@wAY GGwFlose@A n9 uun effet sur le flux GGeul wFreset@A peut tout effer wFlose@AY GGyn psse un tleu de rtres l9ojet GGqui v lire le tmpon r a new ghrerryeder@wFtoghrerry@AAY int iY GGyn remet tous les rtres lus dns un tring tring str a 44Y while@@ i a rFred@AA 3a EIA str Ca @hrA iY ystemFoutFprintln@strAY } th @syixeption eA { eFprinttkre@AY }

Je vous laisse le soin d'examiner ce code ainsi que son eet. Il est assez comment pour que vous en compreniez toutes les subtilits. L'objet String(Writer/Reader) fonctionne de la mme faon :
GGkges importer fin d9utiliser l9ojet pile import jvFioFsyixeptionY import jvFioFtringederY import jvFioFtringriterY puli lss win { puli stti void min@tring rgsA { tringriter sw a new tringriter@AY tringeder srY try { swFwrite@4gouou les ros4AY GGeppel l mthode totring GGde notre ojet de mnire tite ystemFoutFprintln@swAY GGwFlose@A n9 uun effet sur le flux GGeul wFreset@A peut tout effer swFlose@AY GGyn psse un tleu de rtres l9ojet GGqui v lire le tmpon

185

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE


sr a new tringeder@swFtotring@AAY int i Y GGyn remet tous les rtres lus dns un tring tring str a 44Y while@@ i a srFred@AA 3a EIA str Ca @hrA iY ystemFoutFprintln@strAY } th @syixeption eA { eFprinttkre@AY }

En fait, il s'agit du mme code, mais avec des objets dirents ! Vous savez prsent comment crire un ux de texte dans un tampon de mmoire. . . Je vous propose maintenant de voir comment traiter les chiers de texte avec des ux de caractres.

Les classes File(Writer/Reader) et Print(Writer/Reader)


Comme nous l'avons vu, les objets travaillant avec des ux utilisent des ux binaires. La consquence est que mme si vous ne mettez que des caractres dans un chier et que vous le sauvegardez, les objets tudis prcdemment traiteront votre chier de la mme faon que s'il contenait des donnes binaires ! Ces deux objets, prsents dans le package java.io, servent lire et crire des donnes dans un chier texte.
import import import import import jvFioFpileY jvFioFpilexotpoundixeptionY jvFioFpileederY jvFioFpileriterY jvFioFsyixeptionY

puli lss win { puli stti void min@tring rgsA { pile file a new pile@4testpileriterFtxt4AY pileriter fwY pileeder frY try { GGgrtion de l9ojet fw a new pileriter@fileAY tring str a 4fonjour tousD mis ros 3n4Y str Ca 4tgomment llezEvous c n4Y GGyn rit l hne fwFwrite@strAY GGyn ferme le flux

186

UTILISATION DE JAVA.NIO
fwFlose@AY GGgrtion de l9ojet de leture fr a new pileeder@fileAY str a 44Y int i a HY GGveture des donnes while@@i a frFred@AA 3a EIA str Ca @hrAiY GGeffihge ystemFoutFprintln@strAY } th @pilexotpoundixeption eA { eFprinttkre@AY } th @syixeption eA { eFprinttkre@AY }

Vous pouvez voir que l'achage est bon et qu'un nouveau chier 9 vient de faire son apparition dans le dossier contenant votre projet Eclipse ! Depuis le JDK 1.4, un nouveau package a vu le jour, visant amliorer les performances des ux, buers, etc. traits par java.io. En eet, vous ignorez probablement que le package que nous explorons depuis le dbut existe depuis la version 1.1 du JDK. Il tait temps d'avoir une remise niveau an d'amliorer les rsultats obtenus avec les objets traitant les ux. C'est l que le package java.nio a vu le jour !

Utilisation de java.nio
Vous l'avez srement devin, nio signie New I/O. Comme je vous l'ai dit prcdemment, ce package a t cr an d'amliorer les performances sur le traitement des chiers, du rseau et des buers. Ce package permet de lire les donnes 10 d'une faon dirente. Vous avez constat que les objets du package java.io traitaient les donnes par octets. Les objets du package java.nio, eux, les traitent par blocs de donnes : la lecture est donc acclre ! Tout repose sur deux objets de ce nouveau package : les channels et les buers. Les channels sont en fait des ux, tout comme dans l'ancien package, mais ils sont amens travailler avec un buer dont vous dnissez la taille. Pour simplier au maximum, lorsque vous ouvrez un ux vers un chier avec un objet FileInputStream, vous pouvez rcuprer un canal vers ce chier. Celui-ci, comFileNotFoundException, et l'criture peut entraner une IOException.

9. Tout comme dans le chapitre prcdent, la lecture d'un chier inexistant entrane l'exception

10. Nous nous intresserons uniquement l'aspect chier.

187

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE bin un buer, vous permettra de lire votre chier encore plus vite qu'avec un BufferedInputStream ! Reprenez le gros chier que je vous ai fait crer dans la sous-section prcdente : nous allons maintenant le relire avec ce nouveau package en comparant le buer conventionnel et la nouvelle faon de faire.
GGkges importer fin d9utiliser l9ojet pile import jvFioFfufferedsnputtremY import jvFioFpileY import jvFioFpilesnputtremY import jvFioFpilexotpoundixeptionY import jvFioFsyixeptionY import jvFnioFfytefufferY import jvFnioFghrfufferY import jvFnioFhnnelsFpileghnnelY puli lss win { puli stti void min@tring rgsA { pilesnputtrem fisY fufferedsnputtrem isY pileghnnel fY try { GGgrtion des ojets fis a new pilesnputtrem@new pile@4testFtxt4AAY is a new fufferedsnputtrem@fisAY GGhmrrge du hrono long time a ystemFurrentimewillis@AY GGveture while@isFred@A 3a EIAY GGemps d9exution ystemFoutFprintln@4emps d9exution ve un uffer onventionnel X 4 C @ystemFurrentimewillis@A E timeAAY GGgrtion d9un nouveu flux de fihier fis a new pilesnputtrem@new pile@4testFtxt4AAY GGyn rupre le nl f a fisFgetghnnel@AY GGyn en dduit l tille int size a @intAfFsize@AY GGyn re un uffer GGorrespondnt l tille du fihier fytefuffer fuff a fytefufferFllote@sizeAY GGhmrrge du hrono time a ystemFurrentimewillis@AY GGhmrrge de l leture fFred@fuffAY GGyn prpre l leture ve l9ppel flip

188

UTILISATION DE JAVA.NIO
fuffFflip@AY GGeffihge du temps d9exution ystemFoutFprintln@4emps d9exution ve un nouveu uffer X 4 C @ystemFurrentimewillis@A E timeAAY GGuisque nous vons utilis un uffer de yte GGfin de ruprer les donnesD nous pouvons utiliser GGun tleu de yte GGv mthode rry retourne un tleu de yte yte tfyte a fuffFrry@AY } th @pilexotpoundixeption eA { eFprinttkre@AY } th @syixeption eA { eFprinttkre@AY } }

La gure 15.9 vous montre le rsultat.

Figure

15.9  Test des objets du package java.nio

Vous constatez que les gains en performances ne sont pas ngligeables. . . Sachez aussi que ce nouveau package est le plus souvent utilis pour traiter les ux circulant sur les rseaux. Je ne m'attarderai pas sur le sujet, mais une petite prsentation est de mise. Ce package ore un buer par type primitif pour la lecture sur le channel, vous trouverez donc ces classes :  IntBuffer ;  CharBuffer ;  ShortBuffer ;  ByteBuffer ;  DoubleBuffer ;  FloatBuffer ;  LongBuffer. Je ne l'ai pas fait durant tout le chapitre an d'allger un peu les codes, mais si vous voulez tre srs que votre ux est bien ferm, utilisez la clause finally, comme je vous le disais lors du chapitre sur les exceptions. Par exemple, faites comme ceci :
GGkges importer fin d9utiliser l9ojet pile GGFFF

189

CHAPITRE 15. LES FLUX D'ENTRE/SORTIE


puli lss win { puli stti void min@tring rgsA { GGxous dlrons nos ojets en dehors du lo try G th yjetsnputtrem oisY yjetyutputtrem oosY try { GGyn trville ve nos ojets

} th @pilexotpoundixeption eA { GGqestion des exeptions } th @syixeption eA { GGqestion des exeptions } finlly{ if@ois 3a nullAoisFlose@AY if@oos 3a nullAoosFlose@AY }

Le pattern decorator
Vous avez pu remarquer que les objets de ce chapitre utilisent des instances d'objets de mme supertype dans leur constructeur. Rappelez-vous cette syntaxe :
htsnputtrem dis a new htsnputtrem@ new fufferedsnputtrem@ new pilesnputtrem@ new pile@4sdzFtxt4AAAAY

La raison d'agir de la sorte est simple : c'est pour ajouter de faon dynamique des fonctionnalits un objet. En fait, dites-vous qu'au moment de rcuprer les donnes de notre objet DataInputStream, celles-ci vont d'abord transiter par les objets passs en paramtre. Ce mode de fonctionnement suit une certaine structure et une certaine hirarchie de classes : c'est le pattern decorator. Ce pattern de conception permet d'ajouter des fonctionnalits un objet sans avoir modier son code source. An de ne pas trop vous embrouiller avec les objets tudis dans ce chapitre, je vais vous fournir un autre exemple, plus simple, mais gardez bien en tte que les objets du package java.io utilisent ce pattern. Le but du jeu est d'obtenir un objet auquel nous pourrons ajouter des choses an de le  dcorer . . . Vous allez travailler avec un objet Gateau qui hritera d'une classe 190

LE PATTERN DECORATOR