Vous êtes sur la page 1sur 389

'

Programmation objet en Java

Xavier Crgut
<cregut@enseeiht.fr>

Octobre 2009

&

X. Crgut

Programmation objet en Java

'

Objectifs du cours
Les objectifs de ce cours sont :
la programmation (oriente) objet en lillustrant avec le langage Java ;
lutilisation de la notation UML (Unified Modeling Language) pour
reprsenter larchitecture statique du systme (diagramme de classes) ;
les exceptions ;
la programmation par contrat ;
les interfaces graphiques (Swing) et la programmation vnementielle ;
des lments mthodologiques.
Remarque : Mme si le langage cible est Java, les concepts prsents ici
peuvent tre appliqus dans le cadre dautres langages objets (C++, Eiffel,
etc.).

&

X. Crgut

Programmation objet en Java

'

Rfrences
[1] Cay S. Horstmann and Gary Cornell. Au cur de Java 2, volume 1 Notions
fondamentales. Campus Press, 8 edition, 2008.
[2] Bruce Eckel. Thinking in Java. Prentice-Hall, 3 edition, 2002.
http://www.mindviewinc.com/Books/.
[3] Joshua Bloch. Java efficace. Vuibert, 2002.
[4] David Flanagan. Java en concentr. OReilly, 5 edition, 2006.
[5] Mark Grand. Patterns in Java : A Catalog of Reusable Design Patterns Illustrated with
UML, volume 1. Wiley, 2 edition, 2002.
[6] Sun. The Source for Java Technology.

http://java.sun.com.

[7] James Gosling, Bill Joy, Guy Steele, and Gilad Bracha. The Java Language Specification.
Addison-Wesley, 3 edition, March 2005. http://java.sun.com/docs/books/jls/.
[8] Bertrand Meyer. Object-oriented software construction. Prentice Hall, 2nd edition, 1997.
[9] Pierre-Alain Muller and Nathalie Gaertner. Modlisation objet avec UML. Eyrolles, 2
edition, 2003.
[10] Martin Fowler. UML 2.0. CampusPress Rfrence, 2004.

&

[11] OMG. UML Resource Page. http ://www.omg.org/uml/.

X. Crgut

Programmation objet en Java

'

Plan du cours

Exemple introductif : approche objet vs approche traditionnelle (C) . . . . . . . . . . . 5


La plateforme Java : caractristiques et outils . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Algorithmique en Java : types, oprateurs, structures de contrle . . . . . . . . . . . . . 38
Paquetages : structuration dune application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Encapsulation : Classes et objet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
Tableaux, String et autres classes de lAPI Java . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Spcification de comportement : les interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Paramtrisation : la gnricit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Hritage et concepts associs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Responsabilit dune classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Programmation par contrat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Classes internes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Quelques API Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
UML, Design patterns, Interfaces graphiques . . . . . . . . . . . . . . . . . . . autres supports

&

X. Crgut

Programmation objet en Java

'

Approche objet : Exemple introductif

Exercice 1 : quation du second degr


Comment rsoudre (afficher les solutions de) lquation du second degr :
avec une approche traditionnelle (langage impratif ou fonctionnel) ;
avec une approche objet.
Remarque : On se limite au cas gnral dune quation avec deux racines
relles.

&

X. Crgut

Programmation objet en Java

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public class quationTraditionnelle {


public static void main (String[] args) {
double a, b, c;
// coefficients de lquation
// Initialiser les coefficients
a = 1;
b = 5;
c = 6;
// Calculer le discriminant
double delta = (b * b - 4 * a * c);
// Calculer les racines (sans contrle de cohrence)
double x1 = (-b + Math.sqrt(delta)) / 2 / a;
double x2 = (-b - Math.sqrt(delta)) / 2 / a;
// Afficher les rsultats
System.out.println("Racine 1 : " + x1);
System.out.println("Racine 2 : " + x2);
}
}

&

X. Crgut

Les quations : version traditionnelle

Programmation objet en Java

'

Approche objet : changement de faon de penser

Principe : Pour pouvoir penser une solution informatique, il faut


substituer la notion de PROGRAMME la notion dORGANISME,
ensemble dobjets pouvant communiquer entre eux.
O2
O4
O1
O5
O3

Les systmes logiciels sont caractriss au premier chef par les objets
quils manipulent, non par la fonction quils assurent.
Ne demandez pas CE QUE FAIT LE SYSTME.
Demandez QUI IL LE FAIT !
Bertrand Meyer

&

X. Crgut

Programmation objet en Java

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Les quations : version (plus) objet

/** Modlisation dune quation du second degr et de sa rsolution.


* @author Xavier Crgut
* @version 1.3
*/
class quation {
/** Coefficients de lquation */
double coeffA, coeffB, coeffC;
/** Solutions de lquation */
double x1, x2;
/** Dterminer les racines de lquation du second degr. */
void rsoudre() {
double delta = // variable locale la mthode rsoudre
this.coeffB * this.coeffB - 4 * this.coeffA * this.coeffC;
this.x1 = (- this.coeffB + Math.sqrt(delta)) / 2 / this.coeffA;
this.x2 = (- this.coeffB - Math.sqrt(delta)) / 2 / this.coeffA;
}
}

Attention : Cette classe quation est simpliste !


&

X. Crgut

Programmation objet en Java

'

Les quations : version (plus) objet

Une quation est caractrise par ses coefficients, ses racines et le fait que la
rsoudre consiste calculer ses racines en fonction de ses coefficients.
On en dduit :
les attributs : ltat dun objet quation (les coefficients et les racines) ;
les mthodes : les actions qui peuvent tre ralises sur un objet de
type quation (rsoudre lquation).
Remarque : On ne sintresse quau cas gnral (deux solutions) de
lquation du second degr coefficients et valeurs dans les rels.
Attention : Outre la remarque prcdente, cette classe est un exemple ne
pas suivre : il est seulement introductif !
Exercice 2 En deuxime lecture, expliquer pourquoi cette classe quation
constitue un exemple ne pas suivre.

&

X. Crgut

Programmation objet en Java

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Programme principal manipulant les quations

class Rsolutionquation {
/** Rsoudre une quation du second degr. */
public static void main (String[] args) {
quation unequation;
// une poigne sur une quation
unequation = new quation();
// cration dun objet quation
// Initialiser les
unequation.coeffA
unequation.coeffB
unequation.coeffC

coefficients
= 1;
= 5;
= 6;

// Calculer les racines de lquation


unequation.rsoudre();
// Afficher les rsultats
System.out.println(" Racine 1 : " + unequation.x1);
System.out.println(" Racine 2 : " + unequation.x2);
}
}

Exercice 3 Dessiner lvolution de la mmoire.


&

X. Crgut

Programmation objet en Java

10

'

Quelques constatations

Une classe ressemble un enregistrement dans lequel on peut mettre la


fois des champs (attributs) et des fonctions (mthodes).
En Java, on les appelle respectivement attributs et mthodes.
En UML on utilise les termes attributs et oprations.
Les objets sont toujours crs dans le tas (allocation dynamique) par
loprateur new.
Les objets ne sont accessibles que par lintermdiaire de poignes (ou
variables dobjet) quivalentes des pointeurs. Le type de la poigne
conditionne les objets qui peuvent lui tre attachs.
Il ny a pas de delete car Java intgre un ramasse-miettes.
La mmoire des variables locales (types lmentaires ou poignes) est
alloue dans la pile (gre par le compilateur).
On utilise la notation pointe pour accder lattribut dun objet ou lui
appliquer une mthode.
&

X. Crgut

Programmation objet en Java

11

'

Autre version en langage C

Une approche traditionnelle intgrant la notion de type abstrait nous


conduit identifier deux constituants pour ce petit exercice :
un module dcrivant lquation (le type Equation et les oprations
associes) ;
un programme principal correspondant la rsolution dune quation
particulire.
En langage C, le module se traduit en deux fichiers :
un fichier dentte equation.h qui contient la spcification (interface) du
module ;
un fichier dimplantation equation.c qui contient limplantation du
module ;
Le programme principal est dans le fichier test_equation.c.

&
X. Crgut

Programmation objet en Java

12

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Le fichier dentte du module : equation.h

/*******************************************************************
* Objectif : Modlisation dune quation du second degr
et de sa rsolution.
*
: Xavier CRGUT <cregut@enseeiht.fr>
* Auteur
* Version : 1.2
******************************************************************/
#ifndef EQUATION__H
#define EQUATION__H
/* Dfinition du type Equation */
struct Equation {
double coeffA, coeffB, coeffC; /* coefficients de lquation */
double x1, x2;
/* racines de lquation */
};
typedef struct Equation Equation;
/* Dterminer les racines de lquation du second degr.
void resoudre(Equation *eq);

&
X. Crgut

#endif

Programmation objet en Java

*/

13

'

Le fichier dimplantation du module : equation.c


1
2
3
4
5
6
7
8
9
10
11
12
13

#include <math.h>
#include "equation.h"
void resoudre(Equation *eq)
{
double delta = /* variable locale la fonction resoudre */
eq->coeffB * eq->coeffB - 4 * eq->coeffA * eq->coeffC;
eq->x1 = (- eq->coeffB + sqrt(delta)) / 2 / eq->coeffA;
eq->x2 = (- eq->coeffB - sqrt(delta)) / 2 / eq->coeffA;
}

Exercice 4 Comparer la fonction rsoudre en C et la mthode rsoudre en


Java.
&

X. Crgut

Programmation objet en Java

14

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#include <stdio.h>
#include <stdlib.h>
#include "equation.h"
int main()
{
Equation uneEquation;
/* Initialiser les
uneEquation.coeffA
uneEquation.coeffB
uneEquation.coeffC

/* notre quation */

coefficients */
= 1;
= 5;
= 6;

/* Calculer les racines de lquation */


resoudre(&uneEquation);
/* Afficher les rsultats */
printf(" Racine 1 : %f\n", uneEquation.x1);
printf(" Racine 2 : %f\n", uneEquation.x2);

&

X. Crgut

Le programme principal : test_equation.c

return EXIT_SUCCESS;

Programmation objet en Java

15

'

De nouvelles constatations

On peut avoir une approche objet mme avec un langage non objet !
Attention : On naura pas tous les bnfices dune approche objet...
sauf faire des choses trs (trop !) compliques.
Dans la version C, il y a sparation entre la spcification (interface) et
limplantation (corps) du module alors quen Java tout est dans une
mme construction syntaxique (la classe), dans un seul fichier.
La fonction resoudre est lextrieur de lenregistrement.
Le paramtre eq de rsoudre a disparu en Java. Il est devenu implicite.
Pour y faire rfrence, on utilise le mot-cl this.
Dans la version C, on utilise #include <math.h>.
En Java, on indique o se trouve llment utilis : Math.sqrt.
Voir aussi CLASSPATH (T. 28). et import (T. 60)
Le new de Java correspondrait un malloc en C. En Java, la mmoire est
libre automatiquement (pas de delete ou free).
&
X. Crgut

Programmation objet en Java

16

'

Plate-formes Java proposes par Sun

J2SE : Java 2 Platform Standard Edition


JRE (Java Runtime Environment) : Java API, JVM... pour excuter une
application/applet Java
JDK (J2SE Development Kit) : JRE + outils de dveloppement
(compilateur...)
J2EE (Java 2 Platform Enterprise Edition) : dveloppement
dapplications multi-couches orientes composants (Entreprise
JavaBeans), web services (servlet, JSP, XML)...
J2ME (Java 2 Platform Micro Edition) : Java pour les tlphones
mobiles, PDA et autres appareils embarqus. Optimis pour la mmoire,
la puissance de traitement et les E/S.
Java Card : fournir un environnement sr sur des cartes avec de faibles
mmoires et capacits de traitement.

&
X. Crgut

Programmation objet en Java

17

'

&

X. Crgut

Programmation objet en Java

18

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

/** Un programme minimal qui, de manire classique, affiche bonjour .


* En Java, tout est dfini dans une classe mme dans le cas du
* programme le plus simple !
*/
public class Bonjour {
// Mthode principale : cest la mthode excute lorsque
// lutilisateur demande dexcuter la classe Bonjour.
// args : les arguments de la ligne de commande (hors java Bonjour)
/** Dire bonjour tout le monde.
* @param args ceux qui dire bonjour
*/
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
// Afficher sur la sortie standard
System.out.println("Bonjour " + args[i]);
}
System.out.println("Bonjour tout le monde !");
/* Les commentaires la C sont aussi disponibles */
}
}

&
X. Crgut

Premier programme Java

Programmation objet en Java

19

'

Principaux outils du J2SE Developer Kit (JDK)


Le JDK (J2SE Developer Kit) est lenvironnement de dveloppement
(minimal) pour Java propos par Sun.
javac : compilateur de sources Java
java : machine virtuelle (interprte code binaire)
javadoc : gnrateur de documentation HTML
jar : constructeur darchives
appletviewer : interprte des Applet
javap : dsassembleur code binaire
jdb : outil de mise au point (interfac avec DDD)
... et bien dautres !
Remarque : Il existe de nombreux IDE (Integrated Development
Environments) pour Java.
&

X. Crgut

Programmation objet en Java

20

'

Le compilateur : javac

Le compilateur javac produit du code intermdiaire (byte code).


javac Bonjour.java

(==> produit Bonjour.class)

Java est donc un langage compil. Le compilateur vous aidera dtecter et


corriger les erreurs dans vos programmes (messages relativement clairs).
Remarque : Depuis la version 1.2, javac calcule les dpendances et compile
tous les fichiers ncessaires. Il suffit donc de compiler la classe principale.
licorne> javac -verbose Rsolutionquation.java
---- extraits de laffichage ---[parsing started Rsolutionquation.java]
[checking Rsolutionquation]
[loading ./quation.java]
[parsing started ./quation.java]
[wrote Rsolutionquation.class]
[checking quation]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/lang/Math.class)]
[wrote ./quation.class]
[total 1148ms]

&
X. Crgut

Programmation objet en Java

21

'

Compilation de Rsolutionquation.java

licorne> javac -verbose Rsolutionquation.java


[parsing started Rsolutionquation.java]
[parsing completed 305ms]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/lang/Object.class)]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/lang/String.class)]
[checking Rsolutionquation]
[loading ./quation.java]
[parsing started ./quation.java]
[parsing completed 5ms]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/lang/System.class)]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/io/PrintStream.class)]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/io/FilterOutputStream.class)]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/io/OutputStream.class)]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/lang/StringBuffer.class)]
[wrote Rsolutionquation.class]
[checking quation]
[loading /opt/j2sdk1.4.0/jre/lib/rt.jar(java/lang/Math.class)]
[wrote ./quation.class]
[total 1148ms]

&
X. Crgut

Programmation objet en Java

22

'

La machine virtuelle Java (JVM) : java

Le code produit par javac tant du code intermdiaire, il ne peut pas tre
directement excut par la machine.
= Il faut donc utiliser une machine virtuelle Java : java dans le JDK :
licorne> java Bonjour Xavier
Bonjour Xavier
Bonjour tout le monde !

On donne en paramtre une classe Java (donc sans extension !) qui doit
contenir la mthode principale main, suivi des ventuels arguments de la
ligne de commande.
Attention : Ne pas mettre dextension derrire le nom de la classe.
licorne> java Bonjour.class
Exception in thread "main" java.lang.NoClassDefFoundError: Bonjour/class
licorne> java Bonjour.java
Exception in thread "main" java.lang.NoClassDefFoundError: Bonjour/java

Le . est le sparateur de paquetages (quivalent des rpertoires).


&

X. Crgut

Programmation objet en Java

23

'

Outil dextraction de documentation : javadoc

Le JDK contient un outil, javadoc, qui engendre automatiquement la


documentation des classes Java partir de leur code source.
javadoc *.java

(==> produit plein de fichiers HTML)

Intrt : La documentation est directement rdige dans le source Java,


avec le code. Ceci facilite sa mise jour et donc favorise (mais ne garantit
pas !) sa cohrence.
javadoc permet une prsentation standardise de la documentation.
Moyen : Cest bien entendu au programmeur de fournir les lments de la
documentation. Il utilise alors des commentaires spcifiques /** */ placs
avant llment documenter.
Attention : Par dfaut, seules les informations publiques sont documentes.
Remarque : Voir principe de lauto-documentation (T. 27).
&
X. Crgut

Programmation objet en Java

24

'

&
X. Crgut

Documentation engendre

Programmation objet en Java

25

'

Les commentaires

Java propose trois types de commentaires :


Les commentaires la C : utiles pour mettre en commentaire plusieurs
lignes de code.
/* Un commentaire qui peut se continuer
sur plusieurs lignes */
/* Exactement comme en C
* et donc ils ne peuvent pas tre imbriqus
*/

Attention : Ces commentaires ne peuvent pas tre imbriqus.


Les commentaires la C++ :
// Ce commentaire se termine avec la fin de la ligne

Avantage : On ne risque pas doublier de les fermer !


Un bon diteur doit permettre de les ajouter et les enlever facilement.
Les commentaires structurs exploits par loutil javadoc.

&
X. Crgut

Programmation objet en Java

26

'

Les commentaires structurs

Objectif : Les commentaires structurs sont extraits par loutil javadoc pour
produire la documentation de la classe au format HTML.
Ces commentaires peuvent contenir :
des tiquettes spcifiques javadoc : elles commencent par @ (@author,
@param, @return, @see, etc.) ;
des lments HTML.
/**
*
*
*
*/

Les commentaires structurs commencent par une double toile (**).


Ils peuvent contenir des lments <strong>HTML</strong>.
Ils sont placs devant lentit quils dcrivent : une classe, un
attribut, une mthode

Principe de lauto-documentation : le concepteur dun module doit


sastreindre exprimer toute linformation sur le module dans le module
lui-mme.

&

X. Crgut

Programmation objet en Java

27

'

Lien avec le gestionnaire de fichiers : CLASSPATH

Par dfaut, les outils du JDK cherchent les classes dans le rpertoire courant.
Si les classes sont dans plusieurs rpertoires, on utilise le classpath :
soit avec loption -classpath des outils du JDK ;
soit avec la variable denvironnement CLASSPATH.
Remarque : Ncessaire ds quon utilise des bibliothques (JUnit,
Log4J...) qui sont dans des rpertoires ou fichiers darchive (.jar) propres.
javac -classpath /usr/local/java/junit/junit.jar:. MaClasseTest.java
java -classpath /usr/local/java/junit/junit.jar:. MaClasseTest

Les classes sont cherches dans junit.jar puis dans le rpertoire courant.
Attention : Ne pas oublier le rpertoire courant !
En utilisant CLASSPATH avec (t)csh :
setenv CLASSPATH /usr/local/java/junit/junit.jar:.
javac MaClasseTest.java
java MaClasseTest

&

X. Crgut

Programmation objet en Java

28

'

Java est un langage simple et familier

familier par sa parent avec C :


structures de contrle ;
types primitifs.
simple par rapport C/C++ :
pas de fichier dentte, pas de prprocesseur ;
pas darithmtique des pointeurs (ni de syntaxe) ;
ni structures, ni unions, ni numrations (ajoutes dans Java 1.5) ;
pas de surcharge des oprateurs ;
pas de conversions de type sans contrle ;
pas de smantique de la valeur pour les objets ;
gestion automatique de la mmoire.
Attention : Java est un langage objets. Il ncessite donc un changement
de point de vue et contient des aspects subtils (hritage, liaison tardive...).

&

X. Crgut

Programmation objet en Java

29

'

Java est un langage robuste


But : liminer les risques derreur (contexte logiciel embarqu ou mobile)
Moyen :
Mcanisme sophistiqu de gestion des erreurs
Mcanisme de typage fort (dtection statique des erreurs)
Lditeur de lien utilise les informations de typage
Conversions de type contrles
Dtection dynamique des dpassements des bornes de tableaux
Mcanisme sophistiqu de gestion mmoire
Contrle de laccs la mmoire (pas de risque dcrasement)
Libration automatique de la mmoire (ramasse-miettes)
&

X. Crgut

Programmation objet en Java

30

'

Java : Une architecture neutre


But : Excuter du code mobile dans un environnement htrogne ou, plus
simplement, excuter le programme sur des machines diffrentes.
Principe : viter les dpendances vis--vis :
du matriel
des couches logicielles : rseau, systme dexploitation, environnement
graphique
Moyen :
Utilisation dune machine virtuelle (processeur abstrait)
Dfinition dune bibliothque standard abstraite instancie pour chaque
environnement (et tendre vers du pur Java)
&
X. Crgut

Programmation objet en Java

31

'

Java : Un langage portable


But :
Un mme code compil sur toutes les architectures produit le mme rsultat
Minimiser les modifications lies au portage machine virtuelle
Moyen :
Bibliothque indpendante
Dfinition (smantique) prcise du langage :
taille, organisation physique des donnes
valeurs par dfaut, minimales, maximales
effets des oprateurs sur les donnes
ordre des calculs
effets des instructions sur la mmoire
&

X. Crgut

Programmation objet en Java

32

'

Java est un langage objets


Bnficier de la meilleure technologie logicielle disponible ce jour
Concepts-cls : Deux concepts majeurs :
Modularit : encapsulation et masquage dinformation (notion de classe)
Extensibilit (relation dhritage)
Technique :
Classes, interfaces, paquetages
Tout est classe (enveloppe wrapper possible pour les types primitifs)
Les objets sont accessibles par des poignes (pointeurs)
Hritage simple des classes
Hritage multiple dinterfaces
Polymorphisme et liaison tardive
Bibliothque trs riche

&
X. Crgut

Programmation objet en Java

33

'

Java : Un langage performant

Byte code adapt pour tre compil la vole (Just In Time) pour
produire puis rutiliser le code associ chaque instruction
Cache mmoire pour viter le chargement (et la vrification) multiple
dune mme classe
Compilation classique pour engendrer un programme propre une
architecture donne avec dition de lien classique (perte mobilit)
Ramasse-miettes : Processus indpendant de faible priorit
La performance dun langage ne se mesure pas qu sa vitesse dexcution
mais aussi au temps de dveloppement requis. Les atouts de Java sont :
Simplicit du langage ( nuancer !)
Vrification statique et dynamique forte
Bibliothque standard trs complte

&
X. Crgut

Programmation objet en Java

34

'

Autres points forts de Java


Java possde dautres points forts qui ne sont pas dvelopps dans ce cours.
Ainsi Java est aussi un langage...
distribu : exploiter simplement les ressources INTERNET (code mobile
avec les applets, servlets, RMI, Corba) ;
scuris : viter les intrusions lies au code mobile ( bac sable , API
de scurit) ;
dynamique (interprt) : acclrer le cycle de dveloppement (dition
des liens dynamique), introspection ;
parallle : Processus lgers (excution parallle dans le mme espace
dadressage) ;
&

X. Crgut

Programmation objet en Java

35

'

Java : un langage mais pas seulement !

En fait, Java cest trois lments :


1. la machine virtuelle Java (JVM), spcification stable depuis 1995 ;
2. le langage Java par lui-mme. Il a connu des volutions jusqu la
version 1.2, un peu la 1.4 (assert) et 1.5 (gnricit, foreach,
numration, ellipse...) ;
3. la bibliothque standard Java. Cest elle qui volue le plus.
Exemples : le modle de gestion des vnements, swing, XML...
Remarquons que pour amliorer sa portabilit, la bibliothque est
principalement dveloppe en Java.
version

1.0

1.1

1.2

1.3

1.4

1.5

1.6

# classes

212

504

1520

1842

2991

3562

7069

23

59

76

135

166

480

# paquetages

&
X. Crgut

Programmation objet en Java

36

'

Origine et historique

Projet SunSoft : Langage pour applications embarques


1991 : Projet Green, Produit *7, Langage Oak (futur Java) = chec !
volution vers INTERNET : Applications mobiles
1994-1995 : navigateur WWW novateur, futur HotJava
1995 : intgration de Java dans Netscape
Les principales versions de Java :
1996 : premire version de Java publie (Java 1.02)
1997 : Java 1.1 (modle des vnements, internationalisation, Java
Beans...)
1998 : Java 1.2 (Swing optimisation de la JVM, ...).
Sun appelle Java 2 les versions de Java.
2001 : Java 1.4 (assertions, amlioration JDBC, regexp...)
2004 : Java 1.5 (gnricit, numration, foreach) : J2SE 5.0
2006 : Java 1.6, Java SE 6
&

X. Crgut

Programmation objet en Java

37

'

Algorithmique en Java

&
X. Crgut

Programmation objet en Java

38

'

La mthode principale
Par dfinition, lorsquon lance la JVM avec une classe, cest sa mthode
principale qui est excute. Elle se dclare de la manire suivante :
public static void main (String[] args) {
...
}

Attention : Tous les mots (sauf args) sont importants !


Les qualificatifs static (T. 103) et public (T. 69) sont obligatoires !
Elle a pour type de retour void (pas de valeur retourne).
Elle prend un seul paramtre de type tableau (T. 127) de chanes de
caractres (T. 135), les arguments de la ligne de commande.
Chaque classe peut dfinir sa mthode principale.
Une classe peut ne pas avoir de mthode principale.
&
X. Crgut

Programmation objet en Java

39

'

Les types primitifs


Les types primitifs comprennent :
les entiers : byte, short, int, long.
Ce sont des entiers signs (il ny a pas dentiers non signs).
les nombres virgule flottante : float, double.
les boolens : boolean (avec les deux valeurs false et true).
les caractres : char (en Unicode)
Quelques proprits des types primitifs :
Ils ont tous une valeur par dfaut (en gnral 0) utilise pour les
initialisations automatiques.
Les entiers ne sont pas compatibles avec les boolens.
Entiers et caractres sont compatibles (attention 3 + a).
&
X. Crgut

Programmation objet en Java

40

'

Les types primitifs : tableau rcapitulatif

Type

byte

bits

Dfaut

Minimum

Maximum

Exemples

-128

+127

-10, 0, 10

short

16

-32768

32767

-10, 0, 10

int

32

231

231 1

-10, 0, 10

long

64

263

263 1

-10L, 0L, 10L

float

32

0.0

IEEE 754

IEEE 754

3.1F, 3.1f, 31e-1f

double

64

0.0

IEEE 754

IEEE 754

3.1, 3D, 1e-4

boolean

false

false

true

char

16

\u0000

\u0000

\uFFFF

a, \n, \

Remarque : Java autorise les conversions entre types condition quil ny


ait pas de perte dinformation (ou prcision).
float x1 = 4;
float x2 = 4.21;

&
X. Crgut

// OK : conversion (coersion)
// Erreur de compilation !

Programmation objet en Java

41

'

Identificateurs
Les identificateurs en Java sont de la forme : lettre (lettre | chiffre) *
Les lettres sont a-z, A-Z, _, ainsi que tout caractre unicode qui
correspond une lettre dans la langue utilise (caractres accentus).
Java comme C et C++ distingue majuscules et minuscules
Conseil : Toujours choisir un identificateur significatif.
Mettre en vidence les diffrents mots dun identificateur. La convention
Java est de mettre linitiale des mots suivants en majuscule (exemple :
idEnPlusieursParties).
Remarque : Le caractres $ fait partie des chiffres mais est rserv
pour des identificateurs engendrs automatiquement. Ne pas lutiliser !
&

X. Crgut

Programmation objet en Java

42

'

Oprateurs relationnels
==
!=
>
>=
<
<=

//
//
//
//
//
//

galit (conversion si types diffrents)


diffrence (non galit)
plus grand que
plus grand que ou gal
plus petit que
plus petit que ou gal

3
4
4
4
3
3

== 3
!= 5
> 3
>= 3
< 4
<= 4

Attention : Ne pas confondre = (affectation) et == (galit) !

Oprateurs arithmtiques
+ * /
%
+
++
--

&

X. Crgut

//
//
//
//
//
//
//

addition et soustraction (op. binaires)


10 + 5 == 15
multiplication et division
10 / 3 == 3
modulo : le reste de la division entire
10 % 3 == 1
oprateur unaire
+10 == 10
oprateur unaire (oppos de loprande)
-10
pr-incrmentation (++x) ou post-incrmentation (x++)
pr-dcrmentation (--x) ou post-dcrmentation (x--)

Programmation objet en Java

43

'

Oprateurs logiques (boolens)


&&
||
!

// ET logique
// OU logique
// NON logique

expr1 && expr2


expr1 || expr2
! expr1

Remarque : Les oprateurs logiques sont valus en court-circuit


(valuation partielle) : ds que le rsultat est connu, lvaluation sarrte.
true || expr
false && expr

// vrai sans avoir valuer expr


// faux sans avoir valuer expr

Formulations quivalentes : (la seconde est prfrable)


A == true
A == false

&

X. Crgut

est quivalent
est quivalent

A
!A

Programmation objet en Java

44

'

Oprateurs sur les bits


expr1 & expr2
expr1 | expr2
expr1 ^ expr2
~ expr1
expr << nb
expr >> nb
expr >>> nb

//
//
//
//
//
//
//

ET bit bit
OU bit bit
XOR bit bit
inverse les bits de loprande
dcalage de expr gauche de nb bits (fois 2)
dcalage de expr droite de nb bits (div 2)
idem >> (sans prservation du signe)

Oprateur conditionnel (si arithmtique)


condition ? valeur_vrai : valeur_faux

Si la condition est vraie, le rsultat est valeur_vrai, sinon cest valeur_faux.


status = (age >= 18) ? "majeur" : "mineur"

Attention : Peut tre difficile lire !


&
X. Crgut

Programmation objet en Java

45

'
1G

2D
3D

4G
5G
6G
7G
8G
9G
10G
11G
12G
13G
14D
15D

Priorit et associativit des oprateurs


[]
accs un tableau
()
.
p.x ou p.m()
++ -post-incrmentation et post-dcrmentation
++ -pr-incrmentation et pr-dcrmentation
+ - ! ~
unaires
(type)
transtypage
new
* / %
+ << >> >>>
< <= > >= instanceof
== !=
&
^
|
&&
||
?:
= += -= *= *= /= %= &= ^= |= <<= >>= >>>=

a + b + c + d
x = y = z = t

&

X. Crgut

// G : associativit gauche ((a + b) + c) + d


// D : associativit droite x = (y = (z = t))

Programmation objet en Java

46

'

Instructions et structures de contrle


Instructions simples
Dclaration de variables
Affectation
Instruction nulle
Instruction compose
Structures de contrle
Conditionnelles : if et switch
Rptitions : while, do, for et foreach
Instructions ne pas utiliser
break (sauf dans un switch)
continue
&

X. Crgut

Programmation objet en Java

47

'

Instructions simples : dclaration de variables

La dclaration de variables est une instruction.


= Les dclarations nont plus tre groupes au dbut dun bloc.
Dclaration dune variable :
<type> <nom> [= <valeur_initiale>];

// rle de la variable

Exemples :
int age, numro, montant;
// viter les dclarations multiples !
int px = 0, py = 0;
// avec initialisation
double x = 55, y = x*x; // utilisation dune expression calcule

Conseil : Ne dclarer une variable que quand on est capable de linitialiser.


Porte : Une variable locale est accessible de sa dclaration jusqu la fin du bloc
dans lequel elle est dfinie.
Attention : Impossible dutiliser un mme identificateur dans un sous-bloc.
Remarque : Le mot-cl final permet de dfinir une (variable) constante !
En fait, une seule affectation possible.

&

final int MAX = 10;

X. Crgut

Programmation objet en Java

48

'

Instructions simples : affectation

Affectation : Donner une nouvelle valeur une variable.


int
i =
j =
j =

i, j, k;
2;
i * (i - 1);
k = i+j;

// affectation avec une expression constante


// la valeur est une expression quelconque
// laffectation renvoie une valeur !

Variantes de laffectation : Loprateur daffectation peut tre combin


avec la plupart des oprateurs :
x +=
x -=
x %=
x |=
...

y
y
y
y

/*
/*
/*
/*

x
x
x
x

=
=
=
=

x
x
x
x

+
%
|

y
y
y
y

*/
*/
*/
*/

|
|
|
|
|

double x = 1.5;
int n = 0;
n += x;
// possible ?
// valeur de n ?

Attention : Si x est une variable dclare du type T, on a :


x #= y est quivalent (T)((x) # (y))
Pr- et post-oprateurs : ++ et -Incrmenter (++) ou dcrmenter ( ) une variable de 1.
&
X. Crgut

Programmation objet en Java

49

'

Instructions simples (suite)


Instruction nulle :
;

// instruction nulle : ne fait rien !

Bloc ou instruction compose : grouper des instructions avec des


accolades pour quelles soient considres comme une seule.
{

&

X. Crgut

// instruction compose
nbAnnes++;
capital = capital * (1 + taux);

Programmation objet en Java

50

'

Conditionnelles : if

if (<condition>)
<instruction>;

if (<condition>) {
<instructions1 >;
} else {
<instructions2 >;
}

Remarque : si on veut mettre plusieurs instructions, il faut utiliser les { }


pour en faire une instruction compose.
Rgle : Toujours mettre les { }.
Attention : En Java, toutes les conditions sont (et doivent tre) boolennes !
if (n > max) {
max = n;
}

if (n1 == n2) {
res = "gaux";
} else {
res = "diffrents";
}

Remarque : Pour reprsenter un SinonSi, utiliser else if.


&
X. Crgut

Programmation objet en Java

51

'

Conditionnelles : switch (choix multiples)

switch (<expression>) {
case <expr_cste1 >:
<instructions1 >;
break;
...
case <expr_csten >:
<instructionsn >;
break;
default:
<instruction>;
}

switch (c) { // c caractre


case o:
case O:
res = "Affirmatif";
break;
case n:
case N:
res = "Ngatif";
break;
default:
res = "!?!?!?!?";
}

Principe : Lexpression est value et lexcution continue la premire


instruction qui suit la 1re expression constante lui correspondant (ou
default). Si un break est rencontr, lexcution se poursuit la fin du switch.
Consquence : Si le mme traitement doit tre fait pour plusieurs cas, il
suffit de lister les diffrents case correspondants conscutivement.
Conseil : Mettre un break aprs chaque groupe dinstructions dun case.
&

X. Crgut

Programmation objet en Java

52

'

Rptitions : while

while (<condition>) {
<instructions>;
}

// nb dannes pour atteindre lobjectif


double taux = 0.03;
double capital = 5000;
double objectif = 10000;
int nbAnnes = 0;
while (capital < objectif) {
nbAnnes++;
capital = capital * (1 + taux);
}

Smantique : Tant que <condition> est vraie, <instructions> (simple ou


bloc) est excute.
Remarque : <instructions> peut ne pas tre excute.
&
X. Crgut

Programmation objet en Java

53

'

Rptitions : do ... while

do {
<instructions>;
} while (<condition>);

// Calculer la racine carre de a


final double EPSILON = 1.e-4;
double a = 2;
// doit tre non nul !
double un = a;
assert a != 0;
double up; // valeur prcdente de un
do {
up = un;
un = (un + a/un)/2;
} while (Math.abs(un - up) > EPSILON);

Smantique : <instructions> est excute puis, tant que <condition> est


vraie, <instructions> est excute.
Remarque : <instructions> est excute au moins une fois.
&
X. Crgut

Programmation objet en Java

54

'

Rptitions : for

for (<init>; <cond>; <incr>) {


<instructions>;
}

for (int i = 1; i < 10; i++) {


System.out.println(i);
}

Smantique : <init> (initialisation) est excute puis, tant que <cond> est
vraie <instructions> et <incr> (incrmentation) sont excutes.
{

// rcriture du for laide du while


<init>;
// initialisation
while (<cond>) {
// condition de continuation
<instructions>; // traitement
<incr>;
// incrmentation
}

Consquence : Une variable dclare dans <init> nest visible que dans le
bloc du for (cas du int i = 1, par exemple).
Conseil : Conserver la smantique du Pour algorithmique : on sait
lavance combien de fois la boucle doit tre excute.
&
X. Crgut

Programmation objet en Java

55

'

Rptitions : foreach
for (<type> <var> : <col>) {
<instructions>;
}

public static void main(String[] args) {


for (String nom : args) {
System.out.println("Bonjour " + nom);
}
}

Vocabulaire : On dit Pour chaque <var> dans <col> (foreach ... in ...).
Smantique : <col> est soit un tableau, soit une collection (en fait un
itrable, T. 346).
Les instructions sont excutes pour <var> prenant chaque valeur de <col>.
Avantage : criture simple conservant la smantique du Pour algorithmique.
Limite : <instructions> ne doit pas modifier le parcours de la collection
(dtect lexcution ConcurrentModificationException). Rgle du 8020 !

&

X. Crgut

Programmation objet en Java

56

'

Instructions ne pas utiliser

Les instructions suivantes sont proposes par Java :


break : arrter lexcution dune boucle ou dun switch ;
continue : arrter litration actuelle dune boucle et passer la suivante.
Attention : Ces deux instructions ne doivent pas tre utilises car elles
violent les principes de la programmation structure.
Exception : Bien sr, le break peut et doit tre utilis dans un switch !
Remarque : En Java, on peut tiqueter les rptitions.
premire: for (int i = 0; i < 7; i++) { // for tiquett premire
System.out.println("i = " + i);
for (int j = 0; j < 4; j++) {
System.out.println("
j = " + j);
if (j == i) {
continue premire;
// ==> passer au i suivant !
}
}
}
System.out.println("Fin !");

&

X. Crgut

Programmation objet en Java

57

'

Paquetages

Programme = ensemble de classes (et interfaces) organises en paquetages.


// fichier A.java
package nom.du.paquetage;
class A { ... }

// paquetage dappartenance
// texte Java de la classe

La directive package doit tre la premire ligne du fichier.


Une classe ne peut appartenir qu un seul paquetage.
La structure des paquetages sappuie sur le systme de fichiers : les
paquetages sont des rpertoires et les classes des fichiers.
Si le paquetage dappartenance nest pas prcis, la classe appartient au
paquetage anonyme (le rpertoire courant).
Convention : Le nom des paquetages est en minuscules : java.lang,
java.util... (qui correspondent java/lang/, java/util/...).

&

X. Crgut

Programmation objet en Java

58

'

Paquetages : droits daccs

Une classe peut tre publique (public) ou locale au paquetage.


// fichier A.java
package un.premier.paquetage;
public class A { ... }
class B { ... }
// fichier B.java
package un.deuxieme.paquetage;
class X { ... }
class Y { ... }
public class B { ... }

un.premier.paquetage
+A
B

un.deuxieme.paquetage

import

X
Y
+B

Une classe dclare publique (public) peut tre utilise depuis dautres
paquetages sinon elle est locale au paquetage.
On peut mettre plusieurs classes dans un mme fichier Java (dconseill)
mais une seule peut tre publique (elle donne son nom au fichier).

Deux paquetages diffrents peuvent utiliser le mme nom de classe.


&

X. Crgut

Programmation objet en Java

59

'

Paquetages : utiliser une classe dun paquetage

qualifier compltement la classe :


java.awt.Color c;

// La classe Color du paquetage java.awt

importer une classe (on a accs la classe sans la qualifier) :


import java.awt.Color;
...
Color c;

// en dbut de fichier
// La classe Color du paquetage java.awt

importer le contenu dun paquetage (on a accs toutes ses classes) :


import java.awt.*;
...
Color c;
Point p;

// en dbut de fichier
// La classe java.awt.Color
// La classe java.awt.Point

Attention aux conflits si un mme nom de classe est utilis dans deux
paquetages ! Le conflit doit tre rsolu en utilisant le nom qualifi.
java.lang.* est import par dfaut : il contient les classes de base, les
classes System, Math, String, etc.

&

X. Crgut

Programmation objet en Java

60

'

Paquetage : intrts

Intrt : Lintrt des paquetages est de :


structurer lapplication en regroupant ses constituants ;
viter les conflits de noms : un mme nom de classe peut tre utilis dans
deux paquetages diffrents (un paquetage dfinit un espace de noms).
Conseil : Pour viter toute ambigut, il est recommand de toujours
utiliser la forme compltement qualifie des classes !
Exemple : java.awt.Color plutt que Color.
Remarque : Nous parlons maintenant des paquetages car ils sont
ncessaires pour comprendre certains lments de Java (droit daccs) ou
certains messages derreurs avec les outils du JDK.
Attention : Les paquetages sont trs importants pour la structuration dun
programme, ou dune bibliothque. Cependant, nous ninsisterons pas sur
cet aspect dans la suite de ce cours.
&
X. Crgut

Programmation objet en Java

61

'

Classes, objets et envois de message

Les objets
Les poignes
Les classes
Les attributs
Les mthodes
Les constructeurs
Les attributs et mthodes de classe

&

X. Crgut

Programmation objet en Java

62

'

Les objets

Un objet est caractris par :


un tat : la valeur des attributs (coeffA, coeffB, etc.) ;
un comportement : les mthodes qui peuvent lui tre appliques
(rsoudre) ;
une identit qui identifie de manire unique un objet (par exemple son
adresse en mmoire).
Remarque : Un objet na de ralit qu lexcution du programme.
Exercice 5 Quel est ltat dune fraction ? Quel est son comportement ?
Attention : Les objets ne sont accessibles que par lintermdiaire de
poignes : Un objet est attach une poigne.
Synonymes de poigne : rfrence, pointeur, accs.

&
X. Crgut

Programmation objet en Java

63

'

Les poignes

Les objets sont allous dynamiquement (dans le tas) : oprateur new.


new quation();

// cration dun objet quation

Il retourne lidentit de lobjet cr. Elle est conserve dans une poigne.
Poigne : Une poigne est une variable dont le type est le nom dune classe.
quation eq;
eq = new quation();

// dclarer une poigne eq de type quation


// crer un objet et lattacher la poigne

La valeur par dfaut dune poigne est null. Elle indique quaucun objet
nest attach la poigne.
Remarque : On peut regrouper dclaration de la poigne et initialisation :
quation eq = new quation();

// en une ligne pour ne pas oublier


// dinitialiser la poigne

Conseil : Prfrer la version o dclaration de la poigne et cration de


lobjet sont faites en mme temps.
&
X. Crgut

Programmation objet en Java

64

'

Notation graphique dun objet

quation eq = new quation();


...
// initialisation, rsolution, etc.
eq: Equation

eq: Equation
coeffA = 1
coeffB = 5
coeffC = 6
x1 = 2
x2 = 3

en UML

identit
de lobjet
poigne
type de la poigne
nom de la poigne

instance de Equation

classe gnratrice

coeffA = 1
coeffB = 5
coeffC = 6
x1 = 2
x2 = 3

attributs et leurs valeurs

rsoudre()

mthodes

reprsentation abstraite (en mmoire)

Remarque : En UML, on peut omettre le nom de lobjet ou de la classe.


Cest donc le soulign qui indique quil sagit dun objet !
Remarque : En UML, les mthodes ne sont pas donnes car tous les objets
dune mme classe possdent les mmes mthodes. Cest implicite.

&

X. Crgut

Programmation objet en Java

65

'

Et aprs ?
Nous avons vu ce quest un objet, comment le crer et lattacher une
poigne.
Mais :
O sont dfinies les caractristiques des objets ? Dans une classe !
Comment peut-on accder aux caractristiques des objets ? Par lenvoi de
messages (ou appel de mthodes) !
Comment initialiser un objet (nous ne savons que le crer) ? Cest
lobjectif des constructeurs !

&
X. Crgut

Programmation objet en Java

66

'

Les classes

Une classe dfinit :


un MODULE : elle regroupe la dclaration des attributs et la dfinition
des mthodes associes dans une mme construction syntaxique ;
class NomDeLaClasse {
// Dfinition de ses caractristiques
}

Les attributs permettent le stockage dinformation (tat de lobjet).


Les mthodes sont des units de calcul (fonctions ou procdures).
La classe est donc lunit dencapsulation et un espace de noms.
un TYPE qui permet de :
crer des objets ;
dclarer des poignes auxquelles seront attachs ces objets.
Les mthodes et attributs dfinis sur la classe comme MODULE pourront
tre appliqus ces objets (par lintermdiaire des poignes).

&
X. Crgut

Programmation objet en Java

67

'

Liens entre objet, poigne, classe et type


Voici quelques affirmations :
Un objet est une instance dune classe.
Un objet est instance dune et une seule classe.
Une poigne a un type qui est le nom dune classe (ou interface, T. 152).
Un objet a pour type le nom de sa classe mais peut avoir dautres types
(voir interfaces T. 152 et hritage T. 196).
On peut initialiser une poigne avec toute expression dont le type est le
mme que celui de la poigne (ou un sous-type, voir interfaces T. 152 et
hritage T. 196).
&
X. Crgut

Programmation objet en Java

68

'

Droit daccs (accessibilit) des caractristiques

Chaque caractristique a un droit daccs. Il existe quatre niveaux de droit


daccs en Java :
public : accessible depuis toutes les classes ;
private : accessible seulement de la classe et daucune autre ;
absence de modifieur de droit daccs : droit daccs de paquetage,
accessible depuis toutes les classes du mme paquetage ;
protected : accessible du paquetage et des classes drives (cf hritage).
Accessible depuis

Droit daccs/Visibilit

une mthode dfinie dans

public

protected

dfaut

private

La mme classe

oui

oui

oui

oui

Une classe du mme paquetage

oui

oui

oui

non

Une sous-classe dun autre paquetage

oui

oui

non

non

Une autre classe dun autre paquetage

oui

non

non

non

Intrt : Les droits daccs permettent le masquage dinformation.


&

X. Crgut

Programmation objet en Java

69

'

Reprsentation UML dune classe


NomDeLaClasse
+attributPublic: int
attributPriv: double
#attributProtg

nom de la classe

attributs

+mthodePublique
mthodePrive(a: double): int
#mthodeProtge(a:int, b:int)

oprations (UML)
mthodes (Java)

La premire partie contient le nom de la classe, la seconde les attributs et la


troisime les mthodes (qui sont appeles oprations en UML).
Les droits daccs sont symboliss par les signes +
respectivement public, private et protected.

&
X. Crgut

Programmation objet en Java

- #

correspondant
%

70

'

Exemples de classes UML


quation
RobotType1
+x: int
+y: int
+direction: int
+avancer(nb: int)
+pivoter()

+coeffA: double
+coeffB: double
+coeffC: double
+x1: double
+x2: double
+rsoudre()

Exercice 6 Proposer la description UML dune classe Fraction qui


reprsente les fractions rationnelles.
&

X. Crgut

Programmation objet en Java

71

'

Attributs
Les attributs permettent de stocker les informations spcifiques dun objet.
Ils se dclarent ncessairement lintrieur dune classe :
/** Documentation javadoc de lattribut */
<modifieurs> Type idAttribut [, idAttribut]* ;
/** coefficient de x<sup>2</sup> */
public double coeffA;

Les modifieurs incluent la dfinition des droits daccs.


Accs un attribut :

poigne.attribut

quation unequation = new quation();


double sol1 = unequation.x1;
// accs en lecture
unequation.coeffA = 1;
// accs en modification

Attention : Erreur de compilation si droit daccs insuffisant !


&

X. Crgut

Programmation objet en Java

72

'
1
2
3
4
5
6
7
8
9
10

Exemple derreur : droit daccs insuffisant

class TestEquationErreur1 {
public static void main(String[] args) {
Equation eq = new Equation();
eq.coeffA = 1;
}
}
class Equation {
private double coeffA;
// ...
}

La compilation donne le rsultat suivant :


TestEquationErreur1.java:4: coeffA has private access in Equation
eq.coeffA = 1;
^
1 error

Remarque : Le compilateur Java sait que lattribut coeffA est dfini dans la
classe Equation mais le droit daccs nest pas suffisant pour tre utilis dans
TestEquationErreur1.
&
X. Crgut

Programmation objet en Java

73

'

Exemple derreur : variable locale non initialise


1
2
3
4
5
6

class TestEquationErreur2 {
public static void main(String[] args) {
Equation eq;
eq.coeffA = 1;
}
}

La compilation donne le rsultat suivant :


TestEquationErreur2.java:4: variable eq might not have been initialized
eq.coeffA = 1;
^
1 error

Remarque : Le compilateur Java vrifie quune variable locale est


initialise avant dtre utilise.
&

X. Crgut

Programmation objet en Java

74

'

Exemple derreur : utilisation dune poigne nulle


1
2
3
4
5
6

class TestEquationErreur3 {
public static void main(String[] args) {
Equation eq = null;
eq.coeffA = 1;
}
}

Lexcution donne le rsultat suivant :


Exception in thread "main" java.lang.NullPointerException
at TestEquationErreur3.main(TestEquationErreur3.java:4)

Attention : Si la poigne est null, lerreur nest signale qu lexcution.

&

X. Crgut

Programmation objet en Java

75

'

Attributs : rgle sur le droit daccs


Rgles : Un attribut devrait toujours tre dclar private pour respecter :
le principe daccs uniforme : lutilisateur na pas savoir sil accde
une information calcule ou stocke
le principe de la protection en criture et permettre ainsi lauteur de la
classe de garantir lintgrit des objets de la classe.
Exercice 7 Dfinir une date avec jour, mois et anne.
Indiquer comment faire pour changer la valeur du mois.
Indiquer comment faire pour obtenir la valeur du mois.

&
X. Crgut

Programmation objet en Java

76

'

Mthodes

Dfinition : Une mthode est une unit de calcul (fonction au sens de C)


qui exploite ltat dun objet (en accs et/ou en modification).
Une mthode est identifie par sa classe, son nom, le nombre et le type de
ses paramtres (surcharge T. 83).
Elle possde galement un type de retour qui est void si elle ne retourne
rien (procdure).
Elle a un code entre accolades.
Syntaxe
/** Documentation javadoc de la mthode dcrivant lobjectif de la mthode.
* Les paramtres et le retour de la mthode sont galement documents :
* @param nomParamtre description de nomParamtre
* @return description de linformation retourne (si non void)
*/
<modifieurs> TypeRetour idMthode( [Type1 p1[, Type p]*]) {
...
}

&

X. Crgut

Programmation objet en Java

77

'

Mthodes : exemples

Dfinir les mthodes set et delta sur la classe Equation.


/** Initialiser une quation partir de la valeur de ses coefficients.
* @param a coefficient de x<sup>2</sup>
* @param b coefficient de x
* @param c coefficient constant
*/
public void set(double a, double b, double c) {
this.coeffA = a;
this.coeffB = b;
this.coeffC = c;
}
/** Obtenir le discriminant de lquation.
* @return le discriminant de lquation
*/
private double delta() {
return this.coeffB * this.coeffB - 4 * this.coeffA * this.coeffC;
}

Remarque : delta() est private car elle na pas tre utilise de lextrieur.

&
X. Crgut

Programmation objet en Java

78

'

Mthodes : utilisation

Une mthode est toujours applique sur une poigne (comme un attribut) et
est excute sur lobjet associ cette poigne.
poigne.mthode(p1, ..., pn);

// Forme gnrale (envoi de message)

quation eq = new quation();


eq.set(1, 5, 6);
double delta = eq.delta();
eq.rsoudre();
eq.delta();

// Crer un objet quation attach eq


// Initialiser lquation (mthode void)
// Utiliser une mthode non void

quation eq2 = null;


eq2.set(1, 4, 4);

// pas dobjet attach eq


// ==> NullPointerException

// Valide mais quel intrt ?

Remarque : Appliquer une mthode sur une poigne null provoque une
exception (NullPointerException).
Liaison statique : Le compilateur accepte lappel p.m(a1 , ...,an ) ssi il
existe, dans la classe dfinissant le type de la poigne p, une mthode m
darit n telle que les types de a1 , ..., an sont compatibles avec sa signature.
&
X. Crgut

Programmation objet en Java

79

'

Mthodes : le paramtre implicite this

Une mthode est applique un objet, appel rcepteur, (gnralement


travers une poigne) et manipule ltat de cet objet.
Le rcepteur est un paramtre implicite car il napparat pas dans la
signature de la mthode. lintrieur du code de la mthode, on peut y faire
rfrence en utilisant le mot-cl this.
public void set(double a,
double b, double c) {
this.coeffA = a;
this.coeffB = b;
this.coeffC = c;
}

Rq :

this

public void set(double a,


double b, double c) {
coeffA = a; // this implicite !
coeffB = b;
coeffC = c;
}

est ncessaire si un paramtre porte le mme nom quun attribut.

Conseil : Mettre this.


Exercice 8 crire une mthode suprieur (>) si infrieur (<) est dfinie.

&

X. Crgut

Programmation objet en Java

80

'

Dfinir une classe


Exercice 9 : Compteur
Un compteur a une valeur (entire) qui peut tre incrmente dune unit.
Elle peut galement tre remise 0. On suppose galement quil est
possible dinitialiser le compteur partir dune valeur entire positive.
9.1 Modliser en utilisant la notation UML la classe Compteur.
9.2 crire un programme de test de la classe Compteur.
9.3 crire en Java la classe Compteur.
9.4 Comment tre sr que la valeur du compteur est toujours positive ?
&

X. Crgut

Programmation objet en Java

81

'

Afficher une quation

Premire ide : dfinir une mthode afficher pour faire eq.afficher()


1
2
3
4
5

/** Afficher cette quation. */


public void afficher() {
System.out.print(this.coeffA + "*x2 + "
+ this.coeffB + "*x + " + this.coeffC + " = 0");
}

Deuxime ide : faire directement : System.out.println(eq);


Compile, sexcute mais affiche : quation@8814e9
Java utilise la mthode toString() (si dfinie dans la classe, voir T. 224
et 217) pour convertir lobjet en chane de caractres. En dfinissant :
1
2
3
4
5
6
7

/* Obtenir la reprsentation de cette quation sous forme


* dune chane de caractres. */
public String toString() {
return "" + this.coeffA + "*x2 + "
+ this.coeffB + "*x + "
+ this.coeffC + " = 0";
}

on obtient alors laffichage : 1.0*x2


&
X. Crgut

+ 5.0*x + 6.0 = 0

Programmation objet en Java

82

'

Surcharge

Dfinition : En Java, indiquer le nom dune mthode nest pas suffisant


pour lidentifier. Il faut prciser :
la classe laquelle elle appartient ;
son nom ;
son nombre de paramtres ;
le type de chacun de ses paramtres.
Exemple : Les mthodes suivantes sont toutes diffrentes :
class A {
void afficher()
// afficher sans paramtre
void afficher(int i)
// afficher un entier
void afficher(long i)
// afficher un entier long
void afficher(String str)
// afficher une chane
void afficher(String s, int largeur); // sur une certaine largeur
void afficher(String s, int largeur, char mode); // mode == c, g, d
void afficher(int nbFois, String str);
// contre-exemple !
}

&

X. Crgut

Programmation objet en Java

83

'

Surcharge : rsolution

Le mme nom peut tre utilis pour nommer des mthodes diffrentes.
= Pour rsoudre un appel de mthode, le compilateur sappuie galement
sur le nombre et le type des paramtres effectifs :
// On suppose que lon est dans
afficher(10);
afficher(10L);
afficher("Bonjour", 20, c);
afficher("Bonjour");
afficher();
afficher(true);
afficher(20, "Bonjour");

le
//
//
//
//
//
//
//

corps dune mthode de la classe A


afficher(int)
afficher(long)
afficher(String, int, char)
afficher(String)
afficher()
Erreur la compilation
afficher(int, String)

Intrt : viter de multiplier les noms (afficherInt, afficherLong, etc.).


Conseil : Respecter Le sens sous-entendu par le nom de la mthode.
Exercice 10 Expliquer comment la surcharge permet de simuler des
valeurs par dfaut aux paramtres de mthodes ( la C++).
Exercice 11 Quelles mthodes de Fraction pourraient tre surcharges ?
&

X. Crgut

Programmation objet en Java

84

'

Exemples de surcharge

Exercice 12 On considre la classe suivante. Indiquer pour chaque appel


dans la mthode main quelle est la mthode rellement appele.
class TestSurcharge {
static void m0(int a, int b)
static void m1(double a, double b)
static
static
static
static

void
void
void
void

m2(double
m2(double
m2(int a,
m2(int a,

a, double b)
a, int b)
double b)
int b)

static void m3(double d, int i)


static void m3(int i, double d)

{ System.out.println("m0(i,i)"); }
{ System.out.println("m1(d,d)"); }
{
{
{
{

System.out.println("m2(d,d)");
System.out.println("m2(d,i)");
System.out.println("m2(i,d)");
System.out.println("m2(i,i)");

{ System.out.println("m3(d,i)"); }
{ System.out.println("m3(i,d)"); }

public static void main(String[] args) {


m0(1, 1);
m1(1, 1);
m2(1, 1);
m0(2, 2.0);
m1(2, 2.0);
m2(2, 2.0);
m0(3.0, 3);
m1(3.0, 3);
m2(3.0, 3);
m0(4.0, 4.0);
m1(4.0, 4.0);
m2(4.0, 4.0);
}

&
}

X. Crgut

}
}
}
}

Programmation objet en Java

m3(1, 1);
m3(2, 2.0);
m3(3.0, 3);
m3(4.0, 4.0);

85

'

Surcharge et espace de noms

Il est possible de dfinir la mme mthode (mme nom, mme nombre de


paramtres, et mmes types de paramtres) dans deux classes diffrentes.
class A {
/** afficher en commenant
* par un dcalage */
void afficher(int dcalage);
}

class B {
/** afficher nb fois */
void afficher(int nb);
}

Pour savoir quelle mthode choisir, le compilateur sappuie sur le type du


rcepteur (le type de la poigne sur laquelle la mthode est applique).
= La classe dfinit un espace de noms.
A x1;
// poigne x1 de type A
B x2;
// poigne x2 de type B
...
// les initialisations de x1 et X2
x1.afficher(5);
// afficher(int) de la classe A
x2.afficher(10);
// afficher(int) de la classe B

Remarque : Pour certains auteurs, il sagit de surcharge. Pour nous, ce sont


des espaces de noms diffrents.
&

X. Crgut

Programmation objet en Java

86

'

Mthodes : passage de paramtres


Java na quun seul mode de passage de paramtres : le passage par valeur.
Remarque : Si le paramtre est un objet , cest donc un passage par
valeur de la poigne qui est quivalent un passage par rfrence de lobjet.
Consquences : On peut en dduire que :
les modifications apportes un paramtre de type primitif ne sont pas
visibles du programme appelant ( de variables locales initialises) ;
les modifications apportes un objet attach un paramtre de type
poigne sont visibles du programme appelant ;
les modifications de la valeur de la poigne (raffectation) ne seront pas
visibles du programme appelant.
Remarque : Ceci est galement vrai pour le retour dune fonction !
&

X. Crgut

Programmation objet en Java

87

'

Passage de paramtres : exemple


Exercice 13 : Comprendre le passage de paramtres en Java
tant donne la classe Compteur dfinie dans lexercice 9 et dont le texte est
donn listing 2, nous dfinissons la classe TestParametres (listing 1).
Son excution donne le rsultat suivant :
a = 10
c = 11
c = 11

Expliquer les rsultats obtenus lors de lexcution de TestParametres.

&
X. Crgut

Programmation objet en Java

88

'

$
Listing 1 Le fichier TestParametres.java

public class TestParametres {


static void incrmenter(int n)
{ n++; }
static void incrmenter(Compteur cptr) { cptr.incrmenter(); }
static void reset(Compteur cptr)
{ cptr = new Compteur(); }
public static void main(String[] args) {
int a = 10;
incrmenter(a);
System.out.println("a = " + a);

// Valeur de a ?

Compteur c = new Compteur();


c.set(10);
incrmenter(c);
System.out.println("c = " + c.getValeur());

// valeur de c ?

reset(c);
System.out.println("c = " + c.getValeur());

// valeur de c ?

}
}

&

X. Crgut

Programmation objet en Java

89

'

Listing 2 Le fichier Compteur.java

/** Dfinition dun compteur avec incrmentation.


Xavier Crgut
* @author
1.4 */
* @version
public class Compteur {
private int valeur;
// valeur du compteur
/** Augmenter dune unit le compteur */
public void incrmenter()
{ this.valeur++; }

&

/** Obtenir la valeur du compteur.


* @return la valeur du compteur.
*/
public int getValeur()

{ return this.valeur; }

/** Remettre zro le compteur */


public void raz()

{ this.set(0); }

/** Modifier la valeur du compteur.


* @param valeur la nouvelle valeur du compteur
*/
public void set(int valeur) { this.valeur = valeur; }

X. Crgut

Programmation objet en Java

90

'

Constructeurs

Rappel : La cration dun objet ncessite en fait deux tapes :


1. La rservation de la zone mmoire ncessaire. Ceci est entirement
ralis par le compilateur ( partir des attributs de la classe).
2. Linitialisation de la zone mmoire. Le compilateur ne peut, a priori,
faire quune initialisation par dfaut des attributs.
Il y a alors risque davoir une initialisation incorrecte, ou non conforme aux
souhaits de lutilisateur (exemple : Fraction, Date, etc.).
Les constructeurs permettent alors :
au programmeur dindiquer comment un objet peut tre initialis ;
au compilateur de vrifier que tout objet cr est correctement initialis.
Exemple : Une quation peut (doit !) tre initialise partir de la donne
des valeurs de ses coefficients.

&

X. Crgut

Programmation objet en Java

91

'

Les constructeurs en Java

En Java, un constructeur ressemble une mthode mais :


il a ncessairement le mme nom que la classe ;
il ne peut pas avoir de type de retour ;
Exemple : Un constructeur pour les quations
/** Initialiser une quation partir de ses coefficients ... */
public quation(double a, double b, double c) {
this.coeffA = a;
this.coeffB = b;
this.coeffC = c;
}

Remarque : Un constructeur a un droit daccs (idem attributs et


mthodes).
Attention : Mettre un type de retour supprime le caractre constructeur .
On a alors une simple mthode !

&

X. Crgut

Programmation objet en Java

92

'

Constructeur et surcharge

Mme si le nom dun constructeur est impos, la surcharge permet de


dfinir plusieurs constructeurs pour une mme classe.
Exemple : On peut souhaiter initialiser une quation partir de la somme et
du produit de ses racines.
/** Initialiser une quation partir de la somme
* et du produit de ses racines
* @param somme somme des racines
* @param produit produit des racines
*/
public quation(double somme, double produit) {
this.coeffA = 1;
this.coeffB = - somme;
this.coeffC = produit;
}

Exercice 14 Peut-on dfinir un constructeur qui initialise une quation


partir de ses deux solutions ? Pourquoi ?

&
X. Crgut

Programmation objet en Java

93

'

Appel dun autre constructeur de la classe

Problme : Plutt que davoir les mmes trois affectations que dans le
premier constructeur, pourquoi ne pas utiliser le premier constructeur ?
On peut le faire en utilisant this(...) :
/** Initialiser une quation partir de la somme
* et du produit de ses racines
* @param somme somme des racines
* @param produit produit des racines
*/
public quation(double somme, double produit) {
this(1, -somme, produit);
// Appel au constructeur quation(double, double, double)
// Cet appel est ncessairement la premire instruction !
}

Attention : Lappel lautre constructeur est ncessairement la premire


instruction du constructeur.
Bien sr, les paramtres effectifs de this(...) permettent de slectionner
lautre constructeur.
&

X. Crgut

Programmation objet en Java

94

'

Cration dun objet

La cration dun objet en Java est alors :


new <Classe>(<paramtres effectifs>);

Les paramtres effectifs sont fournis par lutilisateur de la classe et sont


utiliss par le compilateur pour slectionner le constructeur appliquer
(surcharge).
Si aucun constructeur nest trouv, le compilateur signale une erreur.
x

new quation(1, 5, 6);

// OK

+ 5x + 6

new quation(2, 1);


new quation(10);
new quation();

2
// OK
x - 2x + 1
// Incorrect !
// Incorrect !

Consquence : Le constructeur permet de rendre atomique la rservation de


la mmoire et son initialisation.

&
X. Crgut

Programmation objet en Java

95

'

Le constructeur par dfaut

On appelle constructeur par dfaut le constructeur qui ne prend pas de


paramtres.
Justification : Cest le constructeur utilis si aucun paramtre nest fourni
lors de la cration dun objet.
Rgle : Le constructeur par dfaut est rgi par deux rgles :
1. Si aucun constructeur nest dfini sur une classe, le systme synthtise
un constructeur par dfaut (qui ne fait rien), le constructeur prdfini.
2. Ds quun constructeur est dfini sur une classe, le constructeur par
dfaut synthtis par le systme disparat.
Remarque : Le programmeur peut toujours dfinir un constructeur par
dfaut... mais y a-t-il intrt ?

&
X. Crgut

Programmation objet en Java

96

'

Un constructeur nest pas une mthode


Mme si un constructeur ressemble une mthode, ce nest pas une
mthode :
il na pas de type de retour ;
il a une syntaxe dappel spcifique (associ loprateur new) ;
il ne peut pas tre appliqu sur un objet (sauf lors de sa cration) ;
il ne peut pas tre redfini dans une classe drive (cf hritage T. 195).
le caractre de constructeur ne shrite pas (cf hritage T. 195).

&

X. Crgut

Programmation objet en Java

97

'

Autres manires dinitialiser un objet

Outre les constructeurs, Java permet au programmeur de dfinir :


des valeurs par dfaut pour les attributs. Elles remplacent alors les
valeurs par dfaut du langage ;
des initialiseurs. Ce sont des instructions mises entre accolades. Sil y a
plusieurs initialiseurs, ils sont excuts dans lordre dapparition.
Exemple : La classe Fraction.
public class Fraction {
private int num;
// valeur par dfaut de Java : 0
private int dn = 1; // valeur par dfaut du programmeur : 1
{
// initialiseur
num = 0;
dn = 5;
}
{
// initialiseur 2
dn = 1;
}
}
// dn prendra successivement les valeurs : 0, 1, 5 et 1

&

X. Crgut

Programmation objet en Java

98

'

Initialisation dobjet : Bilan

Voici ce que fait Java lors de la cration dun objet :


1. Initialisation des attributs avec la valeur par dfaut de leur type ;
2. Utilisation des valeurs par dfaut fournies par le programmeur ;
3. Excution des initialiseurs dans leur ordre dapparition ;
4. Excution du constructeur :
si aucun constructeur nest dfini sur la classe, cest le constructeur
prdfini qui est utilis. Le programmeur ne doit pas fournir de
paramtre au constructeur ;
si au moins un constructeur est dfini sur la classe, le programmeur
doit fournir des paramtres (ventuellement aucun !) qui permettent
au compilateur de choisir lun des constructeurs de la classe.
Conseil : Prfrer les constructeurs explicites aux autres initialisations
(valeurs par dfaut, initialiseurs, constructeur par dfaut synthtis).
&
X. Crgut

Programmation objet en Java

99

'

Destructeurs

Destructeur : mthode appele automatiquement quand un objet disparat


(quand sa mmoire est libre). Il est le pendant du constructeur.
Consquence : Son code contient les traitements raliser lors de la
disparition de lobjet : libration des ressources utilises (mmoire...), etc.
Attention : Il ne peut y avoir quun seul destructeur par classe.
En Java : En Java, le destructeur est :
protected void finalize()

En Java, le ramasse-miettes rend souvent inutile la dfinition du destructeur.


Attention : En raison du ramasse-miettes, aucune garantie nexiste en Java
sur quand le destructeur sera appel... ou sil sera rellement appel.
= Dfinir une mthode explicite (dispose, close, destroy, etc.)...
Et dire aux utilisateurs de penser lappeler (documentation) !
&
X. Crgut

Programmation objet en Java

100

'

Les attributs et mthodes de classe


Exercice 15 On considre une classe Date qui a pour attributs lanne, le
numro du mois et le numro du jour dans le mois. On souhaite dfinir sur
cette classe une mthode incrmenter qui fait passer la date au lendemain.
Comment crire le code de cette mthode ?

&

X. Crgut

Programmation objet en Java

101

'

Attributs et mthodes de classe : on les a dj vus !

Que penser de lexpression suivante :


Math.sqrt(4)

// racine carre de 4

sqrt(double) est bien une mthode mais elle nest pas applique un objet
mais la classe Math. Cest une mthode de classe.
On constate que sqrt(double) travaille exclusivement sur son paramtre.
Que penser de linstruction suivante :
System.out.println("Que suis-je ?");

out est un attribut (puisquil nest pas suivi de parenthses) mais il est
appliqu une classe (System). Cest parce quil nest pas spcifique dun
objet particulier : la sortie standard est la mme pour tout le monde !
Cest en fait un attribut de classe.

&
X. Crgut

Programmation objet en Java

102

'

Attributs et mthodes de classe : en Java

On distingue :
attributs et mthodes dinstance : toujours appliqus un objet
(ventuellement this). On les appelle simplement attributs et mthodes ;
attributs et mthodes de classe : appliqus une classe, non un objet.
Syntaxe : Cest le modifieur static qui indique si un attribut ou une
mthode est de classe ou non.
Droit daccs : Les mmes que pour les attributs et mthodes dinstance.
public class Math {
public static double sqrt(double) {}
}

public class System {


public static PrintStream out;
}

Utilisation : NomClasse.attribut ou NomClasse.mthode(...)


Si NomClasse est la classe courante , il peut tre omis.
Question : Que penser de la mthode principale ?
En UML : On souligne la caractristique de classe (ou on la prfixe par $).
&
X. Crgut

Programmation objet en Java

103

'

Attribut de classe

Dfinition : Un attribut de classe est un attribut non spcifique un objet


donn mais commun (et partag par) tous les objets de la classe.
Intrt : quivalent une variable globale dont la porte est la classe.
Exemple : Compter le nombre dquations cres.
Le compteur est une information relative la classe mais qui doit tre mise
jour par chacune des instances (dans chaque constructeur de la classe).
public class quation {
private static int nbCres = 0;

// initialisation explicite

public quation(double a, double b, double c) {


nbCres++;
// idem : quation.nbCres++;
...
// inutile de modifier les autres constructeurs
}
// sils sappuient sur celui-ci : this(...)
}

Attention : viter ! Comment compter deux sortes dquations ?


&

X. Crgut

Programmation objet en Java

104

'

Initialisation des attributs de classe

Les attributs de classe sont initialiss au chargement de la classe.


Ils sont initialiss avec la valeur par dfaut de leur type, puis la valeur par
dfaut fournie par le programmeur, et enfin par linitialiseur statique (un
bloc dinstructions prcd de static).
class UneClasse
static public
public static
public static
static {
k = 1;
j = 5;
}

{
int i;
// initialis 0 (valeur par dfaut des int)
int j = 10; // valeur par dfaut du programmeur
int k;

// initialiseur statique
// il est utile pour les initialisations complexes (tableaux)
// 5 remplace la valeur 10 fournie comme dfaut

Rgle : Comme ceux dinstance, dclarer les attributs de classe private.


Attention : Les attributs de classe limitent lextensibilit (variable globale)
&

X. Crgut

Programmation objet en Java

105

'

Mthodes de classe

Dfinition : Une mthode de classe est une mthode indpendante de toute


instance de la classe. Elle est donc applique une classe et non un objet.
Consquence : Une mthode de classe na pas de paramtre implicite (this)
et ne peut donc pas utiliser les attributs et mthodes dinstance de sa classe.
public class Date {
private int jour, mois, anne;
static private int nbCres = 0;

// nombre de dates cres

public static boolean estBissextile(int a) {


return ((a % 4) == 0)
// divisible par 4
&& ((a % 100 != 0)
// et non divible par 100
|| (a % 400 == 0)); // sauf si divisible par 400
// impossible dutiliser this.annee ou annee car static !
}
public static int getNbCres() {
return nbCres;
}
}
Exercice

&

X. Crgut

16 Quand peut-on (doit-on) dfinir une mthode de classe ?


Programmation objet en Java

106

'

Mthode de classe et accs aux informations dune classe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class A {
private int i;
static private int k;
public void incI() {
this.i++;
}

// attribut dinstance
// attribut de classe
// mthode dinstance

public static void incK() { // mthode de classe


k++;
}

&
X. Crgut

public static void m(A a) { // mthode de classe


i++;
this.i++;
incI();
this.incI();
k++;
incK();
a.k++;
a.i++;
new A().i++;
}

Programmation objet en Java

107

'

Le rsultat de la compilation :
1
2
3
4
5
6
7
8
9
10
11
12
13

MethodeClasseAccesMembres.java:14: non-static
referenced from a static context
i++;
^
MethodeClasseAccesMembres.java:15: non-static
be referenced from a static context
this.i++;
^
MethodeClasseAccesMembres.java:16: non-static
be referenced from a static context
incI();
^
MethodeClasseAccesMembres.java:17: non-static
be referenced from a static context
this.incI();
^
4 errors

&
X. Crgut

Programmation objet en Java

variable i cannot be

variable this cannot

method incI() cannot

variable this cannot

108

'

Information de classe : Bilan


Un attribut de classe :
est accessible de nimporte o (variable globale),
MAIS est souvent un frein pour lvolution de lapplication (par exemple
sil faut diffrencier lattribut suivant les contextes).
= viter les attributs de classe !... Ou tre conscient des limites induites !
Une mthode de classe :
est accessible de partout ( partir de sa classe),
permet de conserver le caractre symtrique de certaines mthodes
(comparaison),
MAIS pas daccs aux informations dinstance,
NI redfinition possible (voir T. 152 et 196), NI liaison dynamique
(T. 168 et 217)

&
X. Crgut

Programmation objet en Java

109

'

Fabrique statique

Une utilisation recommande des mthodes de classe est de sen servir la


place des constructeurs.
public class Equation {
...
protected Equation(double a, double b, double c) { ... }
public static Equation depuisCoefficients(double a, double b, double c) {
return new Equation(a, b, c);
}
public static Equation depuisSommeEtProduit(double s, double p) {
return new Equation(1, -s, p);
}
public static Equation depuisRacines(double x1, double x2) {
return Equation.depuisSommeEtProduit(x1 + x2, x1 * x2);
}
}

Remarque : Le constructeur nest pas public pour obliger utiliser les


fabriques statiques.
&
X. Crgut

Programmation objet en Java

110

'

Fabrique statique : utilisation


class Exemple {
public static void
Equation eq1 =
Equation eq2 =
Equation eq3 =
...
}

main(String[] arguments) {
Equation.depuisCoefficients(1, 5, 6);
Equation.depuisSommeEtProduit(2, 1);
Equation.depuisRacines(2, 1);

&

X. Crgut

Programmation objet en Java

111

'

Discussion sur les fabriques statiques

Avantages :
les mthodes de classe ont un nom. Il peut donc tre explicite !
une mthode de classe nest pas oblige de crer un nouvel objet
chaque appel. On peut retourner un objet dj cr.
la mthode peut retourner un objet dun sous-type : Voir Interface
(T. 152) et Hritage (T. 196).
Inconvnients :
pas de diffrence syntaxique entre fabrique statique et mthodes de classe
dviation de la norme (les constructeurs !)
= difficile de retrouver les fabriques statiques dans la documentation
Quelques conventions pour nommer : valueOf (conversion de type),
getInstance.
2me lecture : pourquoi le constructeur est dfini protected et non private ?
&

X. Crgut

Programmation objet en Java

112

'

Importation statique

Il existe une variante de la clause import qui permet daccder directement


aux attributs et mthodes de classe.
1
2
3
4
5
6
7
8
9

import static java.lang.System.out; // importe une caractristique


import static java.lang.Math.*;
// ou toutes
public class ImportationStatiqueMath {
public static void main(String[] args) {
out.println(sqrt(PI));
System.out.println(Math.sqrt(Math.PI));
}
}

Intrt : Il est relativement faible :


crire sqrt plutt que Math.sqrt ;
utiliser directement des constantes : RED au lieu Color.RED ;
En fait, il vise viter de mauvaises pratiques : hriter (T. 195) des
classes Math ou java.awt.Color.

&
X. Crgut

Programmation objet en Java

113

'

lments mthodologiques

&
X. Crgut

Programmation objet en Java

114

'

Les classes du point de vue des utilisateurs

Jusqu maintenant, nous avons dfini une classe en nous plaant du point
de vue du programmeur charg de la raliser. Il est intressant de se placer
du point de vue des programmeurs qui lutiliseront (les utilisateurs ).
Point de vue du programmeur : une classe est compose de :
attributs : stockage dinformations (conservent ltat de lobjet) ;
mthodes : units de calculs.
Point de vue de lutilisateur : une classe est un ensemble de :
requtes : informations qui peuvent tre demandes la classe ;
commandes : services raliss par la classe.
Une requte correspond soit un attribut (information stocke), soit une
mthode (information calcule).
Lutilisateur de la classe doit accder de la mme manire une
information, quelle soit calcule ou stocke. Cest le principe de laccs
uniforme. En Java, il est donc ncessaire de dfinir des mthodes daccs.
&

X. Crgut

Programmation objet en Java

115

'

Illustration : rponse lexercice 9 (Compteur)

1. Dfinir la vue utilisateur


Compteur
requtes
valeur : int
commandes
raz
incrmenter
set(valeur : int)

public class Compteur {


public int getValeur()

{ ... }

public void raz()

{ ... }

public void incrmenter()

{ ... }

public void set(int valeur) { ... }


}

Chaque requte et chaque commande devient une mthode


La requte valeur devient soit getValeur(), soit valeur()
On sait donc comment utiliser un compteur !
&
X. Crgut

Programmation objet en Java

116

'

2. Dfinir le(s) constructeur(s)


Compteur
requtes
valeur : int
commandes
raz
incrmenter
set(valeur : int)
constructeurs
Compteur(valeur : int)

public class Compteur {


public Compteur(int valeur) { ... }
public int getValeur()

{ ... }

public void raz()

{ ... }

public void incrmenter()

{ ... }

public void set(int valeur) { ... }


}

On sait donc aussi crer un compteur.


&
X. Crgut

Programmation objet en Java

117

'

3. Programme de test
1
2
3
4
5
6
7
8
9
10
11
12

class TestCompteur {
public static void main(String[] args) {
Compteur c = new Compteur(10);
assert c.getValeur() == 10;
c.incrmenter();
assert c.getValeur() == 11;
c.raz();
assert c.getValeur() == 0;
c.set(5);
assert c.getValeur() == 5;
}
}

Compiler : javac ExempleCompteur.java


Excuter : java -ea ExempleCompteur (ea comme enable assertions)
On excute avant dcrire limplantation de la classe Compteur !
Meilleure technique : utiliser JUnit !

&

X. Crgut

Programmation objet en Java

118

'

4. Dfinir la vue programmeur : choisir les attributs

public class Compteur {


private int valeur;

Compteur
valeur : int
+ getValeur() : int
+ raz
+ incrmenter
+ set(valeur : int)
+ Compteur(valeur : int)

public Compteur(int valeur) { ... }


public int getValeur()

{ ... }

public void raz()

{ ... }

public void incrmenter()

{ ... }

public void set(int valeur) { ... }


}

Il ne reste plus ( !) qu crire le code des mthodes.

&
X. Crgut

Programmation objet en Java

119

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

/** Dfinition dun compteur avec incrmentation.


Xavier Crgut
* @author
@version
1.4 */
*
public class Compteur {
private int valeur;
// valeur du compteur
/** Initialiser un compteur partir de sa valeur initiale.
* @param valeurInitiale valeur initiale du compteur
*/
public Compteur(int valeurInitiale) { this.valeur = valeurInitiale; }
/** Augmenter dune unit le compteur */
public void incrmenter()
{ this.valeur++; }
/** Obtenir la valeur du compteur.
* @return la valeur du compteur.
*/
public int getValeur()

{ return this.valeur; }

/** Remettre zro le compteur */


public void raz()

{ this.set(0); }

/** Modifier la valeur du compteur.


* @param valeur la nouvelle valeur du compteur
*/
public void set(int valeur) { this.valeur = valeur; }

&
X. Crgut

5. crire le code

Programmation objet en Java

120

'

Comment dfinir une classe

Pour dfinir une classe, je conseille de suivre les tapes suivantes :


1. Dfinir la spcification dun point de vue utilisateur :
Spcifier les requtes
Spcifier les commandes
2. Spcifier les constructeurs
3. Prparer les tests
4. Choisir une reprsentation (choix des attributs)
Les attributs sont dfinis private.
5. Implanter les requtes et les commandes sous forme de mthodes.
Ce peut tre une simple mthode daccs pour les requtes qui
correspondent un attribut.
6. Tester au fur et mesure !
&
X. Crgut

Programmation objet en Java

121

'

Conventions de codage : rgles pour nommer


Ces conventions de codage peut tre trouves lURL :
http://java.sun.com/docs/codeconv/index.html

Rgles pour nommer :


paquetage : tout en minuscule (java.lang) ;
classe : les initiales en majuscule (Equation, MaClasse) ;
mthode : en minuscule sauf linitial des mots internes en majuscule
(rsoudre, setCoeffA, maMthode) ;
attribut : comme les mthodes ;
constante : tout en majuscule avec les mots spars par des souligns (_)
(MAX, MA_CONSTANTE).
&
X. Crgut

Programmation objet en Java

122

'

Conventions de codage : structure dun fichier

package ...;

// dfinition du paquetage dappartenance

import ...;

// importation des classes utilises

/**
* Commentaire de documentation de la classe
* @version
Prnom Nom
* @author
*/
public class MaClasse { // ==> Le fichier est MaClasse.java
/* commentaire dimplmentation de la classe */
// variables (attributs) de classe
// variables (attributs) dinstance
// constructeurs
// mthodes.
//

&

Les mthodes sont regroupes par thme


et non par droit daccs.

X. Crgut

Programmation objet en Java

123

'

Conventions de codage : rgles diverses


Indentation : 4 espaces, la tabulation est fixe 8.
Longueur des lignes : 80 caractres maximum. Les lignes sont coupes
de prfrence aprs une virgule ou devant un oprateur.
Dclarer une seule variable par ligne (facilite sa documentation) :
int maVariable;

// sa documentation

Dclarer les variables en dbut de bloc (bof !).


Ne pas mettre de () aprs return (sauf si amliorent la comprhension).
Pas despace entre mthode et (. Mettre un espace entre mot-cl et (,
autour dun oprateur, devant une {, aprs , et ;.
while (Math.sqrt(x) > y) {
...
}

&

X. Crgut

Programmation objet en Java

124

'

Conventions de codage : programmation (1/2)


Ne pas mettre les attributs (de classe ou dinstance) publics.
Dfinir ventuellement des accesseurs et des modifieurs.
Utiliser la classe et non un objet pour accder un attribut ou mthode de
classe.
MaClasse.mthodeDeClasse();
unObjet.mthodeDeClasse();

// OUI
// VITER

Ne pas utiliser directement des constantes littrales (sauf pour -1, 0 et 1).
viter les affectations multiples (a = b = c;) ou dans des expressions
a = (d = b + c) + r;

Utiliser les parenthses dans des expressions mlangeant plusieurs


oprateurs.
&
X. Crgut

Programmation objet en Java

125

'

Conventions de codage : programmation (2/2)

Faire que la structure du programme ressemble votre intention.


viter

prfrer

if (condition) {
return true;
} else {
return false;
}

return condition;

if (condition) {
return x;
}
return y;

return (condition ? x : y);

Mettre XXX dans un commentaire pour signaler un code maladroit mais


qui fonctionne et FIXME pour un code qui ne fonctionne pas.

&

X. Crgut

Programmation objet en Java

126

'

Les tableaux
Les tableaux en Java se rapprochent beaucoup des objets :
ils sont accessibles par une poigne ;
int[] tab1;
int tab2[];
Type[] tab;

// tab1 est une poigne sur un tableau (tab1 == null)


// on peut dclarer les tableaux comme en C
// une poigne tab sur un tableau de Type

ils sont crs dynamiquement en utilisant loprateur new.


tab1 = new int[5]; // cration dun tableau de 5 entiers attach tab1
tab = new Type[capacit];
//cration dun tableau de capacit Type

Mais ce ne sont pas des objets :


ils ont une syntaxe spcifique (les crochets) ;
ils taient le seul type gnrique de Java (paramtr par un type, celui des
lments du tableau) avant la version 1.5.

&

X. Crgut

Programmation objet en Java

127

'

Caractristiques dun tableau

Un tableau non cr ne peut pas tre utilis (NullPointerException)


La capacit du tableau est obtenue par l attribut length.
double tab[] = new double[10];
int nb = tab.length;

// nb == 10 (nb de cases alloues)

Laccs un lment se fait par les crochets ([]).


Les indices sont entre 0 (premier lment) et length-1 (dernier lment)
Sinon erreur signale par lexception ArrayIndexOutOfBoundsException.
for (int i
tab[i]
}
double p =
double d =
double e =

= 0; i < tab.length; i++) {


= i;
tab[0];
tab[tab.length-1];
tab[tab.length];

// premier lment
// dernier lment
// ArrayIndexOutOfBoundsException

Laffectation de deux tableaux est une affectation de poigne (partage).


On peut utiliser System.arraycopy(...).

&
X. Crgut

Programmation objet en Java

128

'

Caractristiques dun tableau (suite)


Lorsquun tableau est cr (new), chacun de ses lments est initialis
avec la valeur par dfaut de son type (false, 0, null).
Il est possible dinitialiser explicitement le tableau :
int[] petitsNbPremiers = { 3, 5, 7, 11,
int nb = petitsNbPremiers.length;
String[] nomJours = { "lundi", "mardi",
nb = nomJours.length;

13 };
// nb == 5
"mercredi", ..., "dimanche" };
// nb == 7

Les tableaux ne peuvent pas tre redimensionns (length ne peut pas


changer de valeur). Voir java.util.ArrayList.
lexception des tableaux de caractres, laffichage par
System.out.println nest pas lisible.

System.out.println("nomJours = " + nomJours);


--> nomJours = [Ljava.lang.String;@bd0108

&
X. Crgut

Programmation objet en Java

129

'

Tableaux dobjets

On peut bien sr crer des tableaux dobjets. Tout fonctionne comme les
tableaux de types lmentaires sauf que le contenu dune case est une
poigne sur un objet du type prcis.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

public class Tableauquations {


public static void main (String args []) {
quation[] systme = new quation[3];
systme[0] = new quation(1, 5, 6);
systme[1] = new quation(4, 4);
for (int i = 0; i < systme.length; i++) {
systme[i].rsoudre();
System.out.print("quation " + (i+1) + " : ");
systme[i].afficher();
System.out.println("x1 = " + systme[i].x1);
System.out.println("x2 = " + systme[i].x2);
}
}
}

&

X. Crgut

Programmation objet en Java

130

'

Rsultat de lexcution

quation 1 : 1.0*x2 + 5.0*x + 6.0 = 0


x1 = -2.0
x2 = -3.0
quation 2 : 1.0*x2 + -4.0*x + 4.0 = 0
x1 = 2.0
x2 = 2.0
Exception in thread "main" java.lang.NullPointerException
at Tableauquations.main(Tableauquations.java:7)

Autre manire dcrire le programme (Java 1.5)


1
2
3
4
5
6
7
8
9
10
11

public static void main (String args []) {


quation[] systme = { new quation(1, 5, 6),
new quation(4, 4), null };
for (quation eq : systme) {
eq.rsoudre();
System.out.print("quation : "); // sans numro !
eq.afficher();
System.out.println("x1 = " + eq.x1);
System.out.println("x2 = " + eq.x2);
}
}

&

X. Crgut

Programmation objet en Java

131

'

Tableaux plusieurs dimensions

Les tableaux deux dimensions (ou plus) sont en fait des tableaux de
tableaux (de tableaux...). Ils peuvent tre initialiss de deux manires.
1. Allocation de toutes les cases en une seule fois
1
2
3
4
5

int[][] matrice = new int[2][3];


for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
matrice[i][j] = i+j;
afficher(matrice);

Remarque : On a un tableau de tableaux. On peut donc manipuler une


ligne par lintermdiaire dune poigne.
1
2
3
4
5

// permuter les deux premires lignes


int[] ligne = matrice[0];
matrice[0] = matrice[1];
matrice[1] = ligne;
afficher(matrice);

&

X. Crgut

Programmation objet en Java

132

'

Tableaux plusieurs dimensions (suite)

2. Allocation individuelle de chacun des (sous-)tableaux


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

//
Le triangle de Pascal
// Crer le tableau de lignes
int[][] triangle = new int[10][];
// Construire la premire ligne
triangle[0] = new int[2];
triangle[0][0] = triangle[0][1] = 1;
// Construire les autres lignes
for (int i = 1; i < triangle.length; i++) {
// Cration de la (i+1)me ligne du triangle
triangle[i] = new int[i+2];
triangle[i][0] = 1;
for (int j = 1; j < triangle[i].length - 1; j++) {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
triangle[i][i+1] = 1;
}
afficher(triangle);

&
X. Crgut

Programmation objet en Java

133

'

Tableaux plusieurs dimensions : utilisation

Un tableau plusieurs dimensions est un tableau de tableaux dont :


les cases peuvent ne pas tre alloues (null) ;
toutes les cases ( lignes ) nont pas ncessairement la mme capacit.
Exemple : Afficher un tableau deux dimensions dentiers.
1
2
3
4
5
6
7
8
9
10
11
12
13

static void afficher(int[][] mat) { // On suppose mat != null


for (int i = 0; i < mat.length; i++) {
if (mat[i] == null) {
// mat[i] non allou
System.out.println();
} else {
System.out.print(mat[i][0]);
for (int j = 1; j < mat[i].length; j++) {
System.out.print(", " + mat[i][j]);
}
System.out.println();
}
}
}

&

X. Crgut

Programmation objet en Java

134

'

La classe String

Attention : Les String sont des objets. Elles sont donc accessibles au
moyen de poignes.
String
String
String
String
String
String

s0;
s1 =
s2 =
s3 =
s4 =
s5 =

// Une poigne non initialise (ventuellement null)


null;
// Une poigne initialise null
"";
// Une chane de caractres vide
"Bonjour";
new String("Bonjour"); // quivalent mais plus long !
s3 + "Xavier";
// concatnation

s0 et s1 ne sont pas des chanes de caractres mais des poignes nulles !


Les chanes de caractres littrales se notent entre guillemets.
loprateur + correspond la concatnation des chanes de caractres (si
lun des paramtres est une chane).
int valeur = 5;
String s6 = "Total = "+ valeur + .;
String s7 = "Total = "+ (valeur + .);

Attention : Les parenthses changent lvaluation !


&

X. Crgut

Programmation objet en Java

// Total = 5.
// Total = 51

135

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Les String sont des objets


String s1 = "Bonjour";
int lg = s1.length();
// la longueur de la chane : 7
char initiale = s1.charAt(0);
// B
char erreur = s1.charAt(lg);
// -> StringIndexOutOfBoundsException
// les indices sur les chanes vont de 0 length()-1.
String
String
//
//

s2 = s1.substring(0, 3); // "Bon"


s3 = s1.substring(3, 7); // "jour"
substring(int dbut, int fin) : sous-chane comprise
entre les indices dbut inclus et fin exclu.

String
String
String
int p1
int p2

s4 = s1.toUpperCase();
//
s5 = s1.toLowerCase();
//
s6 = s1.replace(o, .);
= s1.indexOf("on");
//
= s1.indexOf("on", 2);
//

BONJOUR
bonjour
// B.nj.ur
1
-1 (non trouv !)

String s7 = "Un texte


avec
des blancs";
String s8 = s7.replaceAll("\\s+", " "); // remplace blancs par espace
String[] mots = s7.split("\\s+");
// mots == { "Un", "texte", "avec", "des", "blancs" }
// replaceAll et split ont une expression rgulire comme paramtre

&
X. Crgut

Les String sont des objets

Programmation objet en Java

136

'

Comparaisons de chanes (String)

Deux types dgalit :


lgalit physique : deux chanes correspondent au mme objet en
mmoire. Cest lgalit de poigne (s1 == s2).
String s1 = "N7 2TR";
boolean estN7 = s1.substring(0, 2) == "N7";

// faux !

lgalit logique : deux chanes sont composes des mmes caractres.


boolean estN7 = s1.substring(0, 2).equals("N7"); // vrai !

Important : VRAI pour tout objet (toute classe), voir T. 224.


Autre comparaison logique :
int res = s1.compareTo(s2); // comparer suivant lordre lexicographique
// ngatif si s1 < s2 ; nul si s1.equals(s2) ; positif si s1 > s2

Rq : quivalence entre s1.equals(s2) et s1.compareTo(s2)

== 0 !

Attention : Une chane de caractres (String) ne peut pas tre altre


(immuable !). Il est donc ncessaire de construire de nouvelles chanes. (voir
StringBuffer, T. 138)
&
X. Crgut

Programmation objet en Java

137

'

La classe StringBuffer
Un StringBuffer est une chane de caractres (comme String ) qui
peut tre modifie !
En plus de la majorit des mthodes de String, StringBuffer propose
append : ajouter la fin de la chane ;
insert : ajouter une position spcifie de la chane.
Ces deux mthodes sont largement surcharges !
Passage de String StringBuffer et inversement :
StringBuffer t1 = new StringBuffer("Bonjour");
StringBuffer t2 = new StringBuffer();
// Chane de longueur 0 !
String s2 = t1.toString();
StringBuffer t3 = new StringBuffer(s2);
StringBuffer t4 = "toto";
// Interdit !

&
X. Crgut

Programmation objet en Java

138

'

Pourquoi String et StringBuffer ?

Le caractre immuable dun String entrane que :


on peut faire du partage sans risque de modification par les autres
= gain de mmoire et de temps (aucune copie ncessaire).
toute modification ncessite la cration dune nouvelle String
= perte de mmoire et de temps (allocation + copie)
StringBuffer permet de faire des modifications sur la mme zone mmoire
et vite donc les rallocations MAIS attention au partage ! ! !
Remarque : StringBuffer est utilise par le compilateur pour implanter la
concatnation des chanes de caractres. Linstruction :
x = "a" + 4 + "c"

est transforme par le compilateur en :


x = new StringBuffer().append("a").append(4).append("c").toString()

&

X. Crgut

Programmation objet en Java

139

'

String ou StringBuffer ? Un exemple !

public class ConcatenerString {


public static void main(String[] args) {
String chane = "";
for (int i = 0; i < 100000; i++) {
chane = chane + x;
}
System.out.println("Longueur de chane = " + chane.length());
}
}
public class ConcatenerStringBuffer {
public static void main(String[] args) {
StringBuffer tampon = new StringBuffer();
for (int i = 0; i < 100000; i++) {
tampon.append(x);
}
String chane = tampon.toString();
System.out.println("Longueur de chane = " + chane.length());
}
}

&

X. Crgut

Programmation objet en Java

140

'

String ou StringBuffer ?

Temps dexcution :
> time java ConcatenerString
Longueur de chane = 100000
real 1335.64
user 1302.43
sys 26.20

> time java ConcatenerStringBuffer


Longueur de chane = 100000
real 0.70
user 0.58
sys 0.06

Les concatnations entre String sont plus claires que les oprations sur
StringBuffer, donc :
Prfrer les StringBuffer si de nombreuses modifications doivent tre
apportes une chane (par exemple dans une boucle).
Prfrer les String pour des affections simples de chanes
(le compilateur fera la transformation en StringBuffer pour vous !).
Voir aussi StringBuilder et http://java.sun.com/developer/
technicalArticles/Interviews/community/kabutz_qa.html

&
X. Crgut

Programmation objet en Java

141

'

Les classes enveloppes


Les types primitifs (int, double, boolean...) ne sont pas des objets.
Cependant, pour chacun des types primitifs, il existe une classe
correspondante, appele classe enveloppe (wrapper) dans java.lang.
Chaque classe enveloppe permet de construire un objet partir dune
valeur du type primitif, et possde une mthode daccs retournant la
valeur du type primitif.
Les instances des classes enveloppes sont des objets non altrables !
Intrt : Les classes enveloppes nont dintrt que si lon a besoin de
considrer les types primitifs comme des objets (T. 179).
Depuis Java 1.5, la conversion entre types primitifs et classes enveloppes
est automatique (auto boxing/unboxing).

&

X. Crgut

Programmation objet en Java

142

'

Exemple : caractristiques de la classe enveloppe Integer

Les constantes de classe :


public static final int MAX_VALUE;
public static final int MIN_VALUE;

// Plus grande valeur entire


// Plus petite valeur entire

Les constructeurs :
public Integer(int);
public Integer(String);

Les mthodes de classe


static int parseInt(String s, int radix);
static int parseInt(String);
static Integer decode(String); // plus gnrale : decode("0xFF")

Les mthodes de conversion vers dautres types


int intValue();
float floatValue();
double doubleValue();
String toString();

&

X. Crgut

Programmation objet en Java

143

'

Exemple dutilisation de la classe Integer (Java 1.4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Integer n1 = new Integer(15);


Integer n2 = new Integer("100");

// construire depuis un int


// construire depuis String

// int i1 = n1;
// Erreur : types diffrents !
int i1 = n1.intValue();
double d2 = n2.doubleValue();
// d2 == 100.0
int i3 = Integer.parseInt("421");
Integer n4 = Integer.decode("0xFFF");

// i3 == 421
// n4 == 4095

boolean test;
// test = n1 == i1;
// test = i1 == n1;

// Types incompatibles
// Types incompatibles

test = n1.intValue() == i1;


test = n1 == new Integer(i1);

// true
// false

// Convertir le premier paramtre de la ligne de commande.


if (args.length > 0) {
Integer n5 = Integer.decode(args[0]);
int i5 = Integer.parseInt(args[0]);
// Attention NumberFormatException !
}

&
X. Crgut

Programmation objet en Java

144

'

Exemple dutilisation de la classe Integer (Java 1.5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Integer n1 = new Integer(15);


Integer n2 = new Integer("100");

// construire depuis un int


// construire depuis String

int i1 = n1;
// en fait : i1 = n1.intValue()
double d2 = n2.doubleValue();
// d2 == 100.0
int i3 = Integer.parseInt("421");
Integer n4 = Integer.decode("0xFFF");
boolean test;
test = n1 == i1;
test = i1 == n1;

// i3 == 421
// n4 == 4095

// true
// true

test = n1.intValue() == i1;


test = n1 == new Integer(i1);

// true
// false

// Convertir le premier paramtre de la ligne de commande.


if (args.length > 0) {
Integer n5 = Integer.decode(args[0]);
int i5 = Integer.parseInt(args[0]);
// Attention NumberFormatException !
}

&
X. Crgut

Programmation objet en Java

145

'

Les numrations

Depuis Java 1.5, il est possible de dfinir des types numrs.


1

public enum Fruit { POMME, POIRE, ORANGE, PRUNE };

public enum Couleur { JAUNE, VIOLET, ORANGE };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class ExempleEnum {
static Couleur getCouleur(Fruit f) {
Couleur resultat = null;
switch (f) {
case POMME: resultat = Couleur.JAUNE; break;
case ORANGE: resultat = Couleur.ORANGE; break;
case PRUNE: resultat = Couleur.VIOLET; break;
}
return resultat;
}
public static void main(String[] args) {
for (Fruit f : Fruit.values()) {
System.out.println(f + " est " + getCouleur(f));
}
}
}

&

X. Crgut

Programmation objet en Java

146

'

Les numrations : proprits

Une numration est une classe.


Chaque valeur est quivalente un attribut de classe constant.
Le mme nom (ORANGE) peut tre utilis dans deux numrations (espaces
de noms diffrents).
On peut utiliser un switch avec une expression de type numration.
Intrt :
vite davoir dfinir des constantes entires.
Contrle de type fort ( la compilation !).
Les constantes ne sont pas compiles dans le code client.
On peut obtenir (name()) et afficher le nom dune valeur.
POMME est JAUNE
POIRE est null

ORANGE est ORANGE


PRUNE est VIOLET

On peut ajouter des mthodes et des attributs dans une classe numre.
&
X. Crgut

Programmation objet en Java

147

'

Relations entre classes

On dit quil y a relation de dpendance entre une classe A et une classe B


si la classe A fait rfrence la classe B dans son texte.
Cette relation peut tre momentane si B apparat comme
un paramtre dune mthode ;
une variable locale.
Cette relation est structurelle si elle dure, cest gnralement le cas quand
B est un attribut. En UML, on fait apparatre une relation entre les classes.
Durer = dure de vie suprieure au temps dexcution dune mthode.
En Java, cette relation correspond, par dfaut, un partage dobjets sauf si
le programmeur ralise explicitement des copies.
En UML elle peut tre prcise : association, agrgation ou composition.
&

X. Crgut

Programmation objet en Java

148

'

Relation entre classes

Une application est compose de plusieurs classes dont le couplage est


caractris par des relations (dutilisation) :
association : couplage faible correspondant une relation symtrique
entre objets relativement indpendants (dures de vie non lies) ;
A

verbe
rle de B
rle de A

agrgation : association non symtrique avec couplage plus fort, relation


de subordination. Cest une relation de type tout-partie ;
A
tout

partie

composition : agrgation forte (par valeur). La dure de vie des objets


partie est lie celle du tout . Pas de partage possible.
A

&
X. Crgut

tout

partie

Programmation objet en Java

149

'

Relations entre classes : exemples


1..*

travaillepour 0..1

Personne

Entreprise
employ
1..*

Train

employeur

Wagon

1..*

Sige

{ordered}
0..1

passager *

0..1

conducteur

Personne

Exercice 17 Dessiner un diagramme de classes faisant apparatre un site


web, des pages HTML et un webmaster .

&

X. Crgut

Programmation objet en Java

150

'

Traduction en Java
0..1

conducteur

0..1

*
passager

Train

Personne

public class Train {


private Personne conducteur;
// Pour une multiplicit de 1 ou 0..1 (null ?)
private Personne[] passagers;
// Au lieu dun tableau, il est prfrable
// dutiliser une structure de donnes adapte.
...
}

La flche indique le sens de navigation de la relation : dun objet train on


peut obtenir le conducteur ou les passagers mais pas linverse.
Agrgation et association se reprsentent de la mme faon en Java.
Pour la composition, plusieurs stratgies sont possibles (voir TD).
&

X. Crgut

Programmation objet en Java

151

'

Interfaces

&
X. Crgut

Programmation objet en Java

152

'

Exercice 18 : Liste de rels


On considre une liste de rels (double) offrant les oprations suivantes :
connatre la taille de la liste (son nombre dlments) ;
obtenir llment la position i de la liste ;
remplacer le ie lment de la liste ;
ajouter un lment dans la liste en position i ;
supprimer llment la position i de la liste.
On doit avoir 0 <= indice < taille sauf pour ajouter car ajouter taille
signifie ajouter en fin. On ne traitera pas les cas derreur.

18.1 Dessiner le diagramme UML de la classe Liste.


18.2 crire une mthode dans une classe OutilsListe qui calcule la somme
des rels dune liste.
18.3 On hsite entre stocker les lments de la liste dans un tableau ou les
chaner. Ceci remet-il en cause le travail fait ?
&

X. Crgut

Programmation objet en Java

153

'

Constatations

On sait ce quest une liste :


on peut donner la signature de chaque mthode ;
on peut en donner la spcification (commentaire javadoc) ;
= On peut donc utiliser une liste.
mais on ne sait pas :
o sont stocks les lments ;
ni, donc, crire le code (implantation) des mthodes ;
= On ne peut pas crire une classe.
Solution : crire une interface Liste (spcifier le comportement).
Remarque : Un jour, il faudra coder les mthodes de la liste et donc faire
un choix de rprsentation. On pourra ainsi avoir plusieurs ralisations :
les lments sont stocks dans un tableau : ListeTab ;
les lments sont chans entre eux : ListeChane.
= ListeTab et ListeChane sont des ralisations de linterface Liste.
&
X. Crgut

Programmation objet en Java

154

'

Notation UML
interface
Liste

une interface

OutilsListe
somme(liste: Liste): double

+taille: int
+item(indice: int): double
+remplacer(indice: int, x: double)
+ajouter(indice: int, x: double)
+supprimer(indice: int)

utilisateur de linterface Liste

une ralisation de Liste


relation de ralisation
ListeTab
lments: double[]
nb: int
+taille: int
+item(indice: int): double
+remplacer(indice: int, x: double)
+ajouter(indice: int, x: double)
+supprimer(indice: int)
+constructor ListeTab(capacite: int)

&
X. Crgut

ListeChane

+taille: int
+item(indice: int): double
+remplacer(indice: int, x: double)
+ajouter(indice: int, x: double)
+supprimer(indice: int)
+constructor ListeChane()

Programmation objet en Java

suivante 0..1
Cellule
premire
0..1

lment: double 0..1

155

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

/** Spcification dune liste. @version 1.6 */


public interface Liste {
/** Obtenir la taille de la liste.
* @return nombre dlments dans la liste */
int taille();
/** Obtenir un lment de la liste.
* @param indice position de llment */
double item(int indice);
/** Remplacer un lment de la liste.
* @param indice indice de llment remplacer
* @param x nouvelle valeur */
void remplacer(int indice, double x);
/** Ajouter un lment dans la liste.
* @param indice indice o doit se trouver le nouvel lment
* @param x lment insrer */
void ajouter(int indice, double x);

&

X. Crgut

Linterface Liste en Java

/** Supprimer un lment de la liste.


* @param indice indice de llment supprimer */
void supprimer(int indice);

Programmation objet en Java

156

'

Quest ce quune interface ?

Dfinition : Une interface est le point de jonction entre des classes utilisant
linterface et des classes la ralisant.
Exemple : Linterface Liste est le point de jonction entre OutilsListe (en
fait, OutilsListe.somme) et ListeTab ou ListeChane.
Essentiel : Une interface dfinit un comportement qui doit tre respect par
ses ralisations et sur lequel peuvent sappuyer ses utilisateurs.
Consquence : La documentation est essentielle ! La signature des
mthodes ne suffit pas : utilisateurs et implmenteurs ne doivent pas pouvoir
avoir des interprtations incompatibles (ou contradictoires).
Intrt : Une interface dfinit un contrat entre utilisateurs et ralisateurs :
les implmenteurs doivent le respecter ;
les utilisateurs savent comment utiliser une interface.
&
X. Crgut

Programmation objet en Java

157

'

Quelques contraintes sur les interfaces


Une interface ressemble une classe mais :
Tous les lments dune interface doivent ncessairement (et ont
implicitement) un droit daccs public.
Justification : Quel intrt de spcifier quelque chose dinaccessible ?
Une interface ne peut pas contenir de code : seule la signature et la
spcification des mthodes sont donnes. Jamais le code !
Justification : Une interface est une spcification et ne doit donc pas :
(trop) contraindre les choix de ses implmenteurs ;
surcharger les utilisateurs de dtails inutiles.
Une interface ne peut pas contenir dattributs (sauf constants, final).
Il nest pas possible de spcifier de constructeur.
Justification : Intrt dun constructeur sans son implantation ?

&
X. Crgut

Programmation objet en Java

158

'

Instances dune interface ?

Constatation : Une interface dcrit seulement un comportement, une


abstraction (elle contient la spcification et non le code).
= Une interface dcrit une notion abstraite.
Consquence : Impossible de crer une instance partir dune interface.
Justification : Quel sens aurait une telle instance ?
1
2
3
4
5
6
7

/** Une interface ne peut pas tre instancie ! */


public class TestListeInstanceErreur {
public static void main(String[] args) {
Liste uneListe = new Liste();
uneListe.ajouter(0, 3.14);
// Quelle signification ?
}
}

TestListeInstanceErreur.java:4: Liste is abstract; cannot be instantiated


Liste uneListe = new Liste();
^

Consquence : Dfinir des classes qui ralisent linterface et qui pourront,


elles, avoir des instances (ListeTab et ListeChane).
&

X. Crgut

Programmation objet en Java

159

'

Ralisation dune interface

Dfinition : On appelle ralisation dune interface une classe qui sengage


dfinir les mthodes spcifies dans cette interface.
Notation : En Java, on utilise le mot-cl implements pour dire quune classe
ralise une interface :
class ListeTab implements Liste {
...
}

Remarque : Une mme classe peut raliser un nombre quelconque


dinterfaces.
class A implements I1, I2, I3 {
...
}

Attention : Si une classe ne dfinit pas toutes les mthodes des interfaces
quelle ralise, elle est dite abstraite (voir T. 225). Incomplte, elle ne
permet pas de crer des instances (comme une interface).
&
X. Crgut

Programmation objet en Java

160

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

/** Ralisation de la Liste en stockant les lments dans un tableau. */


public class ListeTab implements Liste {
private double[] elements; // les lments de la liste
private int nb;
// la taille de la liste
/** Construire une liste vide.
* @param capacite capacit initiale de la liste
*/
public ListeTab(int capacite) {
this.elements = new double[capacite];
this.nb = 0;
// la liste est initialement vide
}

&

X. Crgut

Exemple de ralisation

public int taille() {


return this.nb;
}
public double item(int index) {
return this.elements[index];
}
public void remplacer(int index, double x) {
this.elements[index] = x;
}

Programmation objet en Java

161

'
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

public void supprimer(int index) {


System.arraycopy(this.elements, index+1,
this.elements, index, this.nb-index-1);
this.nb--;
}
public void ajouter(int index, double x) {
if (this.nb >= this.elements.length) { // tableau trop petit !
// agrandir le tableau : pourrait tre plus efficace !
double[] nouveau = new double[this.nb+3]; // 3 arbitraire
System.arraycopy(this.elements, 0, nouveau, 0, this.nb);
this.elements = nouveau;
}
// dcaler les lments partir de index
System.arraycopy(this.elements, index,
this.elements, index+1, this.nb-index);
// ranger le nouvel lment
this.elements[index] = x;
this.nb++;
}
}

&
X. Crgut

Programmation objet en Java

162

'

Exemple de programme utilisant les listes


1
2
3
4
5
6
7
8
9
10
11

/** Programme utilisant les listes ListeTab et ListeChainee. */


public class TestListes {
public static void main(String[] args) {
ListeTab l1 = new ListeTab(5);
ListeChainee l2 = new ListeChainee();
l1.ajouter(0, 3.14);
// quel ajouter ?
l2.ajouter(0, 3.14);
// quel ajouter ?
double v1 = l1.item(0);
double v2 = l2.item(0);
}
}

Remarque : Quel ajouter ? Voir T. 86.

&

X. Crgut

Programmation objet en Java

163

'

Enrichissement dune ralisation


Il est possible dajouter de nouvelles mthodes dans une ralisation (en plus
de celles de linterface).
public class ListeTab implements Liste {
....
public double premier()
public double dernier()
public void trier()

{ return this.elements[0]; }
{ return this.elements[this.nb - 1]; }
{ ... }

Les mthodes premier, dernier et trier sont disponibles dans ListeTab mais
pas dans Liste ni ListeChane.
Remarque : Ces mthodes pourraient tre dfinies sur ListeChane mais
avec un cot non constant pour dernier et trier.
&
X. Crgut

Programmation objet en Java

164

'

Interfaces et poignes

Question : On ne peut pas crer dinstances dune interface... Quel intrt alors ?
Rponse : Une interface permet de dclarer des poignes.
Proprit : Une interface dfinit un type (par exemple, le type Liste).
Intrt : crire des mthodes (et classes) qui sappuient sur des interfaces sans en
connatre les ralisations actuelles... ni futures !
1
2
3
4
5
6
7
8
9
10
11
12
13

/** Quelques mthodes utiles sur les listes. */


public class OutilsListe {
/* Calculer la somme des rels dune liste.
* @param l la liste dont on veut sommer les valeurs
* @return la somme des valeurs de l */
static public double somme(Liste l) {
double resultat = 0;
for (int i = 0; i < l.taille(); i++) {
resultat += l.item(i);
}
return resultat;
}
}

&

Question : Mais que peut bien dsigner le paramtre l de type Liste ?

X. Crgut

Programmation objet en Java

165

'

Sous-type et principe de substitution

Sous-type : Si une classe C ralise une interface I alors le type C est un


sous-type du type I.
Substitution : Si un type T1 est un sous-type de T2 alors partout o T2 est
dclar, on peut utiliser un objet de type T1.
Consquence : Une poigne de type interface peut tre initialise avec tout
objet instance dune classe ralisant cette interface.
1
2
3
4
5
6

Liste l1 = new ListeTab(5);


// principe de substitution
Liste l2 = new ListeChainee(); // principe de substitution
ListeTab lt1 = new ListeTab(10);
double s = OutilsListe.somme(lt1); // principe de substitution
// ListeTab lt = l2;
// Interdit : mauvais sens !
// ListeTab lt = l1;
// Interdit : mauvais sens (voir T. 219) !

Remarque : Tout comme en franais, liste est un terme gnral, abstrait


qui dsigne soit une liste avec tableau, soit une liste chane.

&

X. Crgut

Programmation objet en Java

166

'

Sous-type, principe de substitution et appel de mthode


Pour chaque ligne du code suivant, indiquer si le compilateur laccepte et ce
qui se passe lexcution.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Liste l1 = new ListeTab(5);


// principe de substitution
Liste l2 = new ListeChainee(); // principe de substitution
ListeTab lt1 = new ListeTab(10);
ListeTab lt = l1;
ListeTab lt = l2;
ListeTab lt = lt1;
ListeChainee lc = l1;
ListeChainee lc = l2;

//
//
//
//
//

???
???
???
???
???

l1.dernier();
l2.dernier();
lt1.dernier();
lt.dernier()

//
//
//
//

???
???
???
???

&

X. Crgut

Programmation objet en Java

167

'

Liaison tardive (ou dynamique)

Liste l;
l = new ListeTab(9);
l.ajouter(0, 3.14);

// Dclaration de la poigne l de type liste


// Crer une ListeTab et lattacher l
// Appel de la mthode ajouter(int, double) sur l

Type apparent : Type de (dclaration de) la poigne (Liste).


Type rel : Classe de lobjet attach la poigne (ListeTab).
Rappel : La classe dun objet ne peut pas changer ! Mais, cet objet peut
tre attach des poignes de types diffrents.
Principe : Quand une mthode est applique sur une poigne :
1. le compilateur vrifie que la mthode est dclare dans le type apparent
de la poigne (sinon erreur de compilation) ;
2. la mthode effectivement excute est celle qui est dfinie sur le type
rel de lobjet attach la poigne. Cest la liaison tardive (aussi T. 217).
Exercice 19 Si I est une interface qui spcifie la mthode m() et p une
poigne non nulle dclare de type I, est-on sr que p.m() a un sens ?
&
X. Crgut

Programmation objet en Java

168

'

Affectation renverse

Liste l;
// Dclaration de la poigne l de type liste
l = new ListeTab(9); // Crer une ListeTab et lattacher l
l.ajouter(0, 3.14);
// Appel de la mthode ajouter(int, double) sur l
ListeTab lt;
lt = l;
// Interdit par le compilateur mais ncessaire pour...
lt.trier();
// Trier la liste (opration non disponible sur Liste)

est refuse car Liste nest pas sous-type de ListeTab (mme si lobjet
associ l est bien du type ListeTab) : cest laffectation renverse.
lt = l

Solution : Dire au compilateur de considrer un objet dun nouveau type


lt = (ListeTab) l;

// utiliser avec modration !!!

Attention : Le transtypage ressemble au cast de C. Cependant, cette


conversion est vrifie lexcution (ClassCastException).
Interrogation dynamique de type : oprateur instanceof
if (l instanceof ListeTab) {
((ListeTab) l).trier();
}

&

X. Crgut

if (l instanceof ListeTab) {
ListeTab lt = (ListeTab) l;
lt.trier();
}
Programmation objet en Java

169

'

Les interfaces : Bilan

Intrts dune interface :


Dfinir un contrat entre lutilisateur et le fournisseur dun service
(interface) ;
Possibilit de changer le fournisseur sans changer lutilisateur ;
Possibilit davoir plusieurs ralisations dune mme interface.
= Couplage faible entre utilisateur et fournisseur :
lutilisateur exprime son besoin, linterface,
et il utilise une ralisation quil ne connat pas forcment.
Conseils : Utiliser le type le plus gnral qui possde toutes les oprations
ncessaires quand on dclare le type dun attribut ou dun paramtre de
mthode.
Exemple : Liste l et non ListeTab l si on nutilise pas trier, premier,
dernier.
&
X. Crgut

Programmation objet en Java

170

'

Retour sur ListeTab


Exercice 20 : Questions sur ListeTab
Concernant la classe ListeTab (T. 161), rpondre aux questions suivantes.
20.1 Pourquoi certaines mthodes nont pas de commentaires de
documentation ?
20.2 Dans la mthode ajouter, agrandir le tableau est-il ncessaire ?
20.3 Que se passe-t-il quand la machine virtuelle ne trouve pas assez de
mmoire pour agrandir le tableau ?
20.4 Pourrait-on ne pas agrandir le tableau ? Comment faire alors ?
&

X. Crgut

Programmation objet en Java

171

'

Liste et al. dans la bibliothque Java


Linterface Liste et les classes ListeTab et ListeChane existent dans la
bibliothque Java. Elles sappellent respectivement :
java.util.List (interface) ;
java.util.ArrayList (classe ralisant List) ;
java.util.LinkedList (classe ralisant List) ;
Remarque : Il existe galement :
une classe historique java.util.Vector proche de java.util.ArrayList ;
et bien dautres structures de donnes (voir T. 333).

&
X. Crgut

Programmation objet en Java

172

'

Responsabilit dune classe


.
Exercice 21 Le comportement de la liste est dcrit informellement dans les
commentaires de documentation. Expliquer comment dcrire plus
formellement ce comportement.
Remarque : Les contrats dfinis sur une interface (ici Liste) sappliquent
toutes ses ralisations (ici ListeTab, ListeChane...).

&
X. Crgut

Programmation objet en Java

173

'

Solutions pour formaliser un comportement


Formaliser le comportement, cest dfinir les responsabilits des
classes/interfaces (voir T. 262).
Essentiellement, deux techniques sont possibles :
la programmation par contrat (T. 300) ;
lutilisation des exceptions (T. 268).

&

X. Crgut

Programmation objet en Java

174

'

Programmation par contrat sur linterface Liste

But : Spcifier formellement le comportement des listes. Voir T. 300.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

/** Spcification dune liste. @version 1.6 */


public interface Liste {
//@ public invariant taille() >= 0;

&

X. Crgut

/** Obtenir la taille de la liste.


* @return nombre dlments dans la liste */
/*@ pure @*/ int taille();
/** Obtenir un lment de la liste.
* @param indice position de llment */
//@ requires 0 <= indice && indice < taille();
/*@ pure @*/ double item(int indice);
/** Remplacer un lment de la liste.
* @param indice indice de llment remplacer
* @param x nouvelle valeur */
//@ requires 0 <= indice && indice < taille(); // indice valide
//@ ensures item(indice) == x;
// lment remplac
//@ ensures taille() == \old(taille());
// pas dajout !
void remplacer(int indice, double x);

Programmation objet en Java

175

'
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

$
/** Ajouter un lment dans la liste.
* @param indice indice o doit se trouver le nouvel lment
* @param x lment insrer */
//@ requires 0 <= indice && indice <= taille(); // indice valide
//@ ensures item(indice) == x;
// lment ajout
//@ ensures taille() == \old(taille()) + 1; // un lment de moins
void ajouter(int indice, double x);
/** Supprimer un lment de la liste.
* @param indice indice de llment supprimer */
//@ requires 0 <= indice && indice <= taille(); // indice valide
//@ ensures taille() == \old(taille()) - 1; // un lment de moins
void supprimer(int indice);

Ces contrats ne sont pas complets mais sont suffisants pour dtecter :
les mauvaises utilisations (prconditions compltes)
la plupart des erreurs de programmation classiques dans les ralisations

&

X. Crgut

Programmation objet en Java

176

'

Programmation par contrat sur linterface Liste (version complte)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

/** Spcification dune liste. @version 1.6 */


public interface Liste {
//@ public invariant taille() >= 0;

&

X. Crgut

/** Obtenir la taille de la liste.


* @return nombre dlments dans la liste */
/*@ pure @*/ int taille();
/** Obtenir un lment de la liste.
* @param indice position de llment */
//@ requires 0 <= indice && indice < taille();
/*@ pure @*/ double item(int indice);
/** Remplacer un lment de la liste.
* @param indice indice de llment remplacer
* @param x nouvelle valeur */
//@ requires 0 <= indice && indice < taille(); // indice valide
//@ ensures item(indice) == x;
// lment remplac
//@ ensures (\forall int i;
// autres lments inchangs
//@
0 <= i && i < taille();
//@
i == indice || item(i) == \old(item(i)));
//@ ensures taille() == \old(taille());
// pas dajout !
void remplacer(int indice, double x);

Programmation objet en Java

177

'
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

&
X. Crgut

/** Ajouter un lment dans la liste.


* @param indice indice o doit se trouver le nouvel lment
* @param x lment insrer */
//@ requires 0 <= indice && indice <= taille(); // indice valide
//@ ensures item(indice) == x;
// lment ajout
//@ ensures (\forall int i; // lments avant indice inchangs
//@
i >= 0 && i < indice;
//@
item(i) == \old(item(i)));
//@ ensures (\forall int i; // lments aprs indice dcals
//@
i > indice && i < taille();
//@
item(i) == \old(item(i-1)));
//@ ensures taille() == \old(taille()) + 1; // un lment de moins
void ajouter(int indice, double x);
/** Supprimer un lment de la liste.
* @param indice indice de llment supprimer */
//@ requires 0 <= indice && indice <= taille(); // indice valide
//@ ensures taille() == \old(taille()) - 1; // un lment de moins
//@ ensures (\forall int i; // lments avant indice inchangs
//@
i >= 0 && i < indice;
//@
item(i) == \old(item(i)));
//@ ensures (\forall int i; // lments aprs indice dcals
//@
i >= indice && i < taille();
//@
item(i) == \old(item(i+1)));
void supprimer(int indice);

Programmation objet en Java

178

'

Gnricit

&
X. Crgut

Programmation objet en Java

179

'

Exercice 22 : Gnraliser les listes


Dans lexercice 18 nous avons dfini la notion de liste de rels avec une
interface (Liste) et deux ralisations (ListeTab et ListeChane).
Expliquer comment faire pour avoir des listes dlments de types diffrents
comme par exemple une liste de fractions, une liste de personnes, une liste
de listes de livres, etc.

&
X. Crgut

Programmation objet en Java

180

'

Solutions
Principe : On constate que seul le type des lments de la liste change.
Les algorithmes (donc le code des mthodes) restent identiques.
Solution 1 (mauvaise) : Faire du copier/coller. Il faut :
Renommer tous les fichiers (Liste.java, ListeTab.java...) en prenant un
nouveau nom (ListeDouble, ListeTabDouble, ListeFraction... par exemple).
Remplacer le type double par le nouveau type.
Inconvnients : Mme si ces transformations peuvent tre automatises
elles sont fastidieuses !
Solution 2 (mauvaise) : Celle utilise avant java 1.5. Voir T. 241.
Solution 3 (la bonne) : Utiliser la gnricit ( partir de java 1.5 !)
&

X. Crgut

Programmation objet en Java

181

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

/** Spcification dune liste. @version 1.6 */


public interface Liste<T> {
/** Obtenir la taille de la liste.
* @return nombre dlments dans la liste */
int taille();
/** Obtenir un lment de la liste.
* @param indice position de llment */
T item(int indice);
/** Remplacer un lment de la liste.
* @param indice indice de llment remplacer
* @param x nouvelle valeur */
void remplacer(int indice, T x);
/** Ajouter un lment dans la liste.
* @param indice indice o doit se trouver le nouvel lment
* @param x lment insrer */
void ajouter(int indice, T x);

&

X. Crgut

Version gnrique de linterface Liste

/** Supprimer un lment de la liste.


* @param indice indice de llment supprimer */
void supprimer(int indice);

Programmation objet en Java

182

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Le programme de test

/** Programme utilisant les listes ListeTab et ListeChainee. */


public class TestListes {
public static void main(String[] args) {
ListeTab<Double> l1 = new ListeTab<Double>(5);
ListeChainee<Double> l2 = new ListeChainee<Double>();
Liste<String> ls = new ListeTab<String>(3);
ListeTab<Liste<Double>> ll = new ListeTab<Liste<Double>>(2);
l1.ajouter(0, 3.14);
// quel ajouter ?
l2.ajouter(0, 3.14);
// quel ajouter ?
ls.ajouter(0, "PI");
ll.ajouter(0, l1);
ll.ajouter(1, l2);
double v1 = l1.item(0);
double v2 = ll.item(1).item(0);
String vs = ls.item(0);
}
}

Remarque : Le type des lments des listes est prcis entre < >.
Remarque : On utilise Double et non double car il faut imprativement un
objet. Lauto boxing/unboxing rend ceci transparent.
&

X. Crgut

Programmation objet en Java

183

'

Explications

Une classe gnrique est une classe paramtre par un (ou plusieurs) types.
public interface Liste<T> { ... }
public class Couple<A, B> { ... }

Vocabulaire : T, A et B sont dits variables de type, paramtres de type


formels ou paramtres de gnricit.
Pour obtenir une classe (appele type paramtr), il faut prciser les
paramtres de gnricit (les valeurs des variables de type). On dit
instancier le paramtre .
Liste<Double>, Liste<Personne>...
Couple<String, Livre>...

Attention : La valeur du paramtre de gnricit ne peut pas tre un type


primitif
= Il faut utiliser les classes enveloppes !
&
X. Crgut

Programmation objet en Java

184

'
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
11
12
13
14

/** Dfinition dun couple. */


public class Couple<A, B> {
public A premier;
public B second;
public Couple(A premier_, B second_) {
this.premier = premier_;
this.second = second_;
}

}
import java.awt.Color;
public class TesterCoupleErreur {
public static void main(String[] args) {
Couple<String, Integer> p1 = new Couple<String, Integer>("I", 1);
Couple<Integer, String> p2 = new Couple<Integer, String>(2, "II");
p1.premier = p2.second;
p1.second = p2.premier;
Couple<Color, String> p3 =
new Couple<Color, String> (Color.RED, "rouge");
p3.premier = "VERT";
p3.second = Color.GREEN;

&

X. Crgut

Programmation objet en Java

185

'

Rsultat de la compilation de TesterCoupleErreur


1
2
3
4
5
6
7
8
9
10
11

TesterCoupleErreur.java:11: incompatible types


found
: java.lang.String
required: java.awt.Color
p3.premier = "VERT";
^
TesterCoupleErreur.java:12: incompatible types
found
: java.awt.Color
required: java.lang.String
p3.second = Color.GREEN;
^
2 errors

= Le compilateur dtecte effectivement les erreurs de type.

&
X. Crgut

Programmation objet en Java

186

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

/** Dfinition dun lment simplement chanable sur un type T. */


public class Cellule<T> {
private T element;
private Cellule<T> suivante;
public Cellule(T element_, Cellule<T> suivante_) {
this.element = element_;
this.suivante = suivante_;
}
public Cellule<T> getSuivante() {
return this.suivante;
}
public T getElement() {
return this.element;
}
public void setElement(T nouveau) {
this.element = nouveau;
}

&
X. Crgut

public void setSuivante(Cellule<T> s) {


this.suivante = s;
}

Programmation objet en Java

187

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

/** Ralisation de la Liste en chanant les lments. */


public class ListeChainee<T> implements Liste<T> {
private Cellule<T> premiere;
// premire cellule de la liste
private int nb = 0; // nb de cellules dans la liste

&

X. Crgut

public int taille() {


return this.nb;
}
/** Obtenir une cellule de la liste chane.
* @param index position de la cellule (0 pour la premire)
* @return cellule la position index */
private Cellule<T> cellule(int index) {
Cellule<T> curseur = this.premiere;
for (int i = 0; i < index; i++) {
curseur = curseur.getSuivante();
}
return curseur;
}
public T item(int index) {
return this.cellule(index).getElement();
}
public void remplacer(int index, T x) {

Programmation objet en Java

188

'
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

}
public void ajouter(int index, T x) {
if (index == 0) {
// insertion en tte
this.premiere = new Cellule<T>(x, this.premiere);
} else {
// insertion aprs une cellule
Cellule<T> precedente = cellule(index-1);
Cellule<T> nouvelle = new Cellule<T>(x,
precedente.getSuivante());
precedente.setSuivante(nouvelle);
}
this.nb++;
// une cellule ajoute
}

&
X. Crgut

this.cellule(index).setElement(x);

public void supprimer(int index) {


if (index == 0) {
// insertion en tte
this.premiere = this.premiere.getSuivante();
} else {
// insertion aprs une cellule
Cellule<T> precedente = cellule(index-1);
precedente.setSuivante(precedente.getSuivante().getSuivante());
}
this.nb--;
// une cellule supprime
}

Programmation objet en Java

189

'

Exercice 23 crire une mthode qui change deux lments dun tableau
des indices donns.
Elle doit par exemple pouvoir tre utilise pour changer deux lments
dun tableau de chanes de caractres, dun tableau de points, etc.

&

X. Crgut

Programmation objet en Java

190

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public class GenericiteSwap {


/** Permuter deux lments dun tableau.
* @param tab le tableau
* @param i indice du premier lment
* @param j indice du deuxime lment */
public static <T> void swap(T[] tab, int i, int j) {
T tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
}
public static void main(String[] args) {
String[] ts = { "I", "II", "III", "IV", "V" };
swap(ts, 0, 1);
assert ts[0].equals("II");
assert ts[1].equals("I");
Integer[] ti = { 1, 2, 3, 4, 5 };
// et pas int !!!
swap(ti, 0, 1);
assert ti[0] == 2;
assert ti[1] == 1;
GenericiteSwap.<Integer>swap(ti, 0, 1); // forme complte !

&

X. Crgut

Mthodes gnriques

Programmation objet en Java

191

'

Exercice 24 crire une mthode qui permet dobtenir le plus grand


lment dun tableau. Cette mthode doit fonctionner quelque soit le type
des lments du tableau.

&

X. Crgut

Programmation objet en Java

192

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public class GenericiteMax {


/** Dterminer le plus grand lment dun tableau.
* @param tab le tableau des lments
* @return le plus grand lment de tab */
public static <T extends Comparable<T>> T max(T[] tab) {
T resultat = null;
for (T x : tab) {
if (resultat == null || resultat.compareTo(x) < 0) {
resultat = x;
}
}
return resultat;
}
/** Programme de test de GenericiteMax.max */
public static void main(String[] args) {
Integer[] ti = { 1, 2, 3, 5, 4 };
assert max(ti) == 5;
String[] ts = { "I", "II", "IV", "V" } ;
assert max(ts).equals("V");

&

X. Crgut

Gnricit contrainte : mthode max

Programmation objet en Java

193

'

Gnricit contrainte : Explications

Pour pouvoir dterminer le max, il faut comparer les lments du tableau.


Aussi, nous imposons quils soient comparables (java.lang.Comparable) :
1
2
3
4
5
6
7

public interface Comparable<T> {


/** Compares this object with the specified object for order.
* Returns a negative integer, zero, or a positive integer
* as this object is less than, equal to, or greater than
* the specified object... */
int compareTo(T o);
}

Dans le code de la mthode max, on peut donc utiliser compareTo sur les
lments du tableau.
Integer ralise linterface Comparable<Integer> et String ralise
Comparable<String>. On peut calculer le max des tableaux ti et ts.
Autre exemple : Dictionnaire<Cl extends Hashable, Donne> ;
Remarque : Contraintes multiples : C<T

&
X. Crgut

extends I1 & I2>

Programmation objet en Java

194

'

Relation dhritage

&
X. Crgut

Programmation objet en Java

195

'

Exemple introductif

Exercice 25 : Dfinition dun point nomm


Un point nomm est un point, caractris par une abscisse et une ordonne,
qui possde galement un nom. Un point nomm peut tre translat en
prcisant un dplacement par rapport laxe des X (abscisses) et un
dplacement suivant laxe des Y (ordonnes). On peut obtenir sa distance
par rapport un autre point. Il est possible de modifier son abscisse, son
ordonne ou son nom. Enfin, ses caractristiques peuvent tre affiches.
25.1 Modliser en UML cette notion de point nomm.
25.2 Une classe Point a dj t crite. Que constatez-vous quand vous
comparer le point nomm et la classe Point des transparents suivants ?
25.3 Comment crire la classe PointNomm ?

&

X. Crgut

Programmation objet en Java

196

'

Modlisation de la classe PointNomm

PointNomm
x: double
y: double
nom: String
+getX(): double
+getY(): double
+getNom(): String
+afficher()
+translater(dx: double, dy: double)
+distance(autre: PointNomm): double
+setX(nx: double)
+setY(ny: double)
+nommer(n: String)
PointNomm(vx: double, vy: double, n: String)

&
X. Crgut

Programmation objet en Java

197

'

La classe Point

Point
x: double
y: double
+getX(): double
+getY(): double
+afficher()
+translater(dx: double, dy: double)
+distance(autre: Point): double
+setX(nx: double)
+setY(ny: double)
Point(vx: double, vy: double)

&
X. Crgut

Programmation objet en Java

198

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

La classe Point

// !!! Commentaires de documentation volontairement omis !!!


public class Point {
private double x;
// abscisse
private double y;
// ordonne
public Point(double vx, double vy) { this.x = vx; this.y = vy; }
public
public
public
public

&

X. Crgut

double getX()
double getY()
void setX(double vx)
void setY(double vy)

{
{
{
{

return
return
this.x
this.y

this.x; }
this.y; }
= vx; }
= vy; }

public void afficher() {


System.out.print("(" + this.x + "," + this.y + ")");
}
public double distance(Point autre) {
double dx2 = Math.pow(autre.x - this.x, 2;
double dy2 = Math.pow(autre.y - this.y, 2;
return Math.sqrt(dx2 + dy2);
}
public void translater(double dx, double dy) {
this.x += dx;
this.y += dy;
}

Programmation objet en Java

199

'

Solution 1 : Copier les fichiers

Il suffit ( !) de suivre les tapes suivantes :


1. Copier Point.java dans PointNomm.java
cp Point.java PointNomm.java

2. Remplacer toutes les occurrences de Point par PointNomm.


Par exemple sous vi, on peut faire :
:%s/\<Point\>/PointNomm/g

3. Ajouter les attributs et mthodes qui manquent (nom et nommer)


4. Adapter le constructeur
Beaucoup de problmes :
Que faire si on se rend compte que le calcul de la distance est faux ?
Comment ajouter une coordonne z ?
Peut-on calculer la distance entre un point et un point nomm ?
&

X. Crgut

Programmation objet en Java

200

'

Solution 2 : Utiliser le point (composition)

Point
x: double
y: double
+getX(): double
+getY(): double
+afficher()
+translater(dx: double, dy: double)
+distance(autre: Point): double
+setX(nx: double)
+setY(ny: double)

PointNomm
x: double
y: double
nom: String
+getX(): double
+getY(): double
+getNom(): String
+afficher()
+translater(dx: double, dy: double)
+distance(autre: PointNomm): double
+setX(nx: double)
+setY(ny: double)
+nommer(n: String)

Point(vx: double, vy: double)


pt

PointNomm(vx: double, vy: double, n: String)

&
X. Crgut

Programmation objet en Java

201

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// !!! Commentaires de documentation volontairement omis !!!


public class PointNomme {
private Point pt;
private String nom;
public PointNomme(double vx, double vy, String nom) {
this.pt = new Point(vx, vy);
this.nom = nom;
}
public double getX()
public double getY()
public String getNom()

{ return this.pt.getX(); }
{ return this.pt.getY(); }
{ return this.nom; }

public void translater(double dx, double dy) {


this.pt.translater(dx, dy);
}
public void afficher()

&

X. Crgut

Le code Java correspondant

{ this.pt.afficher(); }

public double distance(PointNomme autre) {


return this.pt.distance(autre.pt);
}
...

Programmation objet en Java

202

'

Discussion sur la solution 2 (utilisation)


Le code de la classe Point est rutilis dans PointNomm
= Pas de code dupliqu !
Il faut dfinir toutes les mthodes dans PointNomm :
les nouvelles mthodes sont codes dans PointNomm (getNom, |nommer)
celles prsentes dans point sont appliques sur lattribut pt
il serait possible de les adapter (par exemple pour afficher)
Toujours impossible de calculer la distance entre Point et PointNomm.
Remarque : le recours la surcharge ne serait pas une bonne solution !
Remarque : On constate quun point nomm est un point particulier.
Un point nomm est un point avec en plus un nom.
&

X. Crgut

Programmation objet en Java

203

'

Solution 3 : Lhritage
Point
x: double
y: double
+getX(): double
+getY(): double
+afficher()
+translater(dx: double, dy: double)
+distance(autre: Point): double
+setX(nx: double)
+setY(ny: double)

PointNomm
x: double
y: double
nom: String
+getX(): double
+getY(): double
+getNom(): String
+afficher()
+translater(dx: double, dy: double)
+distance(autre: PointNomm): double
+setX(nx: double)
+setY(ny: double)
+nommer(n: String)

Point(vx: double, vy: double)

PointNomm(vx: double, vy: double, n: String)

En Java, hriter cest :


1. dfinir un sous-type : PointNomm est un sous-type de Point

&

2. rcuprer dans PointNomm (sous-classe) les lments de Point (super-classe)

X. Crgut

Programmation objet en Java

204

'

Hritage et concepts associs


Les points importants sont :
Hritage : relation de spcialisation/gnralisation
Principe de substitution (induit par lhritage)
Adaptations de lhritage : enrichissement
Hritage et constructeurs
Redfinition et liaison dynamique ;
Interrogation dynamique de type (affectation renverse) ;
Classes abstraites ;
Interfaces ;
Quest ce quun bon hritage ?
Hritage vs utilisation.
&

X. Crgut

Programmation objet en Java

205

'

Hritage

Buts : plusieurs objectifs (non lis) :


dfinir une nouvelle classe :
comme spcialisation dune classe existante ;
comme gnralisation de classes existantes (factorisation des
proprits et comportements communs) ;
dfinir une relation de sous-typage entre classes (substitutionalit) ;
copier virtuellement les caractristiques de classes existantes dans la
dfinition dune nouvelle classe (hritage).
Moyen : La relation dhritage en Java (appele relation de
gnralisation/spcialisation en UML).
Exemples :
PointNomm est une spcialisation de Point (un point avec un nom).
Point est une gnralisation de PointNomm, PointPondr,
PointColor...
&
X. Crgut

Programmation objet en Java

206

'

Notation et vocabulaire

Notation UML

classe parente
classe de base
super classe

Point

relation dhritage (Java)


spcialisation/gnralisation (UML)

PointNomm

classe fille
classe drive
sousclasse

Notation en Java
public class PointNomm
extends Point
{ ... }

// relation dhritage

Vocabulaire : On parle galement danctres et de descendants (transitivit


de la relation dhritage)
&
X. Crgut

Programmation objet en Java

207

'

Exemple dhritage : la classe PointNomm (incomplte)

/** Un point nomm est un point avec un nom. Ce nom peut tre chang. */
public class PointNomme
extends Point
// hritage (spcialisation dun point)
{
private String nom;
/** Initialiser partir de son nom et de ses coordonnes cartsiennes */
public PointNomme(String sonNom, double vx, double vy) {
super(vx, vy); // appel au constructeur de Point (1re instruction)
nom = sonNom;
}
/** Le nom du point nomm */
public String getNom() {
return nom;
}
/** changer le nom du point */
public void nommer(String nouveauNom) {
nom = nouveauNom;
}
}

Remarque : Lhritage vite de faire du copier/coller (toujours dangereux).


Attention : Ne pas confondre extends et import !
&

X. Crgut

Programmation objet en Java

208

'

Enrichissement
Dans la classe drive, on peut ajouter :
de nouveaux attributs (conseil : prendre de nouveaux noms !) ;
private String nom;

de nouvelles mthodes.
public String getNom() { ... }
public void nommer(String nouveauNom) { ... }

Remarque : Ajouter une nouvelle mthode sentend au sens de la


surcharge. Par exemple, sur le PointNomm on peut ajouter :
public void afficher(String prfixe) {
System.out.println(prfixe);
// afficher le prfixe
afficher();
// utiliser le afficher << classique >>
}

qui surcharge la mthode afficher() de Point.


&
X. Crgut

Programmation objet en Java

209

'

Hritage et constructeurs

Principe : Tout constructeur dune classe drive doit appeler un des constructeurs
de la super-classe.
Justification : Hriter dune classe, cest rcuprer ses caractristiques qui doivent
donc tre initialises. Dans un PointNomm, il y a un Point... et un nom.
En pratique : On utilise super suivi des paramtres effectifs permettant au
compilateur de slectionner le constructeur de la classe parente.
public PointNomme(String sonNom, double vx, double vy) {
super(vx, vy); // appel au constructeur de Point (1re instruction)
nom = sonNom;
}

Lappel super doit tre la premire instruction du constructeur !


La classe parente est toujours initialise avant la sous-classe.
Si aucun appel super nest fait, le compilateur appelle automatiquement le
constructeur par dfaut de la classe parente super().
= Do le danger de dfinir un constructeur par dfaut !

&
X. Crgut

Programmation objet en Java

210

'

Utilisation de la classe PointNomm

Exemple dutilisation la classe PointNomm :


1
2
3
4
5
6
7
8
9

PointNomme pn = new PointNomm("A", 1, 2,);


// crer un point "A" de coordonnes (1,2)
pn.afficher();
// (1,2) mthode de Point
pn.translater(-1, 2);
//
mthode de Point
pn.afficher();
// (0,4) mthode de Point
pn.nommer("B");
// mthode de PointNomme
String n = pn.getNom(); // mthode de PointNomme
pn.afficher("Le point est");
// mthode de PointNomme (surcharge)
// Le point est (0, 4)

Remarque : La classe PointNomm a bien hrit de toutes les


caractristiques de Point.
Exercice 26 Lister toutes les caractristiques de la classe PointNomm.
Prciser les droits daccs.
Remarque : afficher() ne donne pas le nom du PointNomm.
&
X. Crgut

Programmation objet en Java

211

'

Hritage et droits daccs

Il faut distinguer laccessibilit pour (les mthodes de) la classe drive


elle-mme et laccessibilit pour les classes utilisant la classe drive :
Une mthode de la classe drive a accs aux caractristiques de la
super-classe dclares public, protected ou visibilit de paquetage.
Les primitives private sont inaccessibles.
Les caractristiques hrites conservent leur droit daccs.
Remarque : La classe drive peut augmenter le droit daccs des
mthodes hrites (une mthode protected peut devenir public). Il suffit
de la redfinir avec le nouveau droit daccs.
Attention : Elle ne peut pas le diminuer (contrainte du sous-typage).
Remarque : Les caractristiques qui taient prives ne sont pas
accessibles par les classes drives. Leur accessibilit ne peut pas tre
augmente !

&

X. Crgut

Programmation objet en Java

212

'

Redfinition de mthode

La classe drive peut donner une nouvelle version (nouveau corps) une
mthode dfinie dans la super-classe (adaptation du comportement).
Exemple : Dans la classe PointNomm, on peut (on doit !) redfinir
afficher pour que le nom du point apparaisse galement.
/** Afficher le point nomm sous la forme nom:(point) */
public void afficher() {
System.out.print(getNom() + ":");
super.afficher();
// utilisation du afficher de Point
}

Remarque : Dans le code de la mthode de la classe drive, on peut faire


rfrence aux mthodes de la classe parente par lintermdiaire de super.
pn.afficher();

// A:(0,4)

mthode de PointNomm !

Attention : La mthode de la sur-classe nest pas masque mais reoit une


nouvelle implantation (les deux correspondent au mme envoi de message).
Attention : La redfinition nest pas de la surcharge !
&
X. Crgut

Programmation objet en Java

213

'

Lannotation @Override

Principe : @Override exprime que lon redfinit une mthode de la


superclasse.
Intrt : Le compilateur vrifie quil sagit bien dune redfinition.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class A {
void uneMethodeAvecUnLongNom(int a) {}
}
class B1 extends A {
@Override
void uneMethodeAvecUnLongNom(Integer a) {}
}
class B2 extends A {
@Override
void uneMethodeAvecUnLongNon(int a) {}
}
class B3 extends A {
@Override
void uneMethodeAvecUnLongNom(int a) {}
}

Question : Quels problmes sont signals par le compilateur ?


&

X. Crgut

Programmation objet en Java

214

'
1
2
3
4
5
6
7

UtilisationOverride.java:5: method does not override or implement a


method from a supertype
@Override
^
UtilisationOverride.java:9: method does not override or implement a
method from a supertype
@Override
^
2 errors

Conseil : Toujours utiliser lannotation @Override quand vous (re)dfinissez


une mthode de manire rendre votre intention explicite pour le
compilateur et les lecteurs !
Attention : Les annotations ont t introduites en Java 5.
&

X. Crgut

Programmation objet en Java

215

'

Principe de substitution

Principe : Linstance dun descendant peut tre utilise partout o un


anctre est dclar.
Justification intuitive : Tout ce qui peut tre demand la super-classe
peut aussi ltre la classe drive.
Attention : Linverse est faux. Linstance dun anctre ne peut pas tre
utilise o un descendant est dclar.
1
2
3
4
5
6
7
8
9

Point p1 = new Point(3, 4);


PointNomme pn1 = new PointNomme("A", 30, 40);
Point q;
// poigne sur un Point
q = p1; q.afficher(); // ?????
q = pn1; q.afficher(); // ?????
PointNomme qn; // poigne sur un PointNomm
qn = p1; qn.afficher(); // ?????
qn = pn1; qn.afficher(); // ?????

Remarque : Le principe de substitution est vrifi la compilation.


&
X. Crgut

Programmation objet en Java

216

'

Rsolution dun appel polymorphe

T p;
// Dclaration de la poigne (type apparent : T)
p = new X(...); // Affectation de la poigne (type rel : X)
...
p.m(a1 , ..., an );
// Appel de la mthode m() sur p

1. Rsolution de la surcharge (vrification statique).


But : Identification de la signature de la mthode excuter.
La classe du type apparent de la poigne (classe T) doit avoir une
mthode m(T1 , ..., Tn ) dont les paramtres correspondent en nombre et
en type aux paramtres effectifs a1 , ..., an .
Si pas de signature trouve Alors erreur de compilation !
Remarque : Le principe de substitution est utilis sur les paramtres !
2. Liaison dynamique ( lexcution, gnralement).
Le systme choisit la version de m(T1 , ..., Tn ) excuter : cest la
dernire (re)dfinition rencontre partant du type T et descendant vers
le type rel de lobjet attach la poigne p (X).
&

X. Crgut

Programmation objet en Java

217

'

Illustration de la liaison tardive


1
2
3
4
5
6
7
8
9
10
11
12

Point p1 = new Point(3, 4);


PointNomme pn1 = new PointNomme("A", 30, 40);
Point q;
// poigne sur un Point
q = p1; q.afficher(); // (3,4)
q = pn1; q.afficher(); // A:(30,40)
PointNomme qn; // poigne sur un Point
qn = p1; qn.afficher(); // INTERDIT !
qn = pn1; qn.afficher(); // A:(30,40)

//
//

type
apparent
Point

PN

type
rel
null
Point
PN
null
Point
PN

qn = q; // Possible ? (Le type rel de q est PointNomm)


qn.afficher()
// ????

Remarque : Le principe est identique celui vu avec les interfaces


(T. 168) !
&
X. Crgut

Programmation objet en Java

218

'

Interrogation dynamique de type

Point p = new PointNomme("A", 1, 2);


PointNomme q;
q = p; // Interdit par le compilateur

Le compilateur interdit cette affectation car il sappuie sur les types


apparents.
Or, un PointNomm est attach p. Laffectation aurait donc un sens.
Cest le pb de laffectation renverse rsolu en Java par le transtypage :
q = (PointNomme) p;

// Autoris par le compilateur

Attention : Le transtypage ressemble au cast de C. Cependant cette


conversion est vrifie lexcution (exception ClassCastException).
Interrogation dynamique de type : oprateur instanceof
if (p instanceof PointNomme) {
((PointNomme) p).nommer("B");
}

&
X. Crgut

if (p instanceof PointNomme) {
PointNomme q = (PointNomme) p;
q.nommer("B");
}

Programmation objet en Java

219

'

Liaison tardive : intrt

Intrt : viter des structures de type choix multiples :


Les alternatives sont traites par le compilateur (sret : pas doubli).
Lajout dune nouvelle alternative est facilit (extensibilit).
En labsence de liaison tardive, il faudrait tester explicitement le type de
lobjet associ une poigne pour choisir quelle mthode lui appliquer :
Point q = ...; // Afficher les caractristiques de q
if (q instanceof PointNomme)
// tester le type rel
// afficher q comme un PointNomme
else if (q instanceof PointColor )
// tester le type rel
// afficher q comme un PointColor
...
else
// Ce nest donc quun point !
// afficher q comme un Point

Remarque : Permet de raliser le principe du choix unique (B. Meyer) :


Chaque fois quun systme logiciel doit prendre en compte un ensemble
dalternatives, un et un seul module du systme doit en connatre la liste
exhaustive .
&

X. Crgut

Programmation objet en Java

220

'

Le modifieur final
Dfinition : Le modifieur final donne le sens dimmuable, de non
modifiable.
Il est utilis pour :
une variable locale : cest une constante (qui doit donc ncessairement
tre initialise lors de sa dclaration) ;
un attribut dinstance ou de classe (qui doit tre ncessairement initialis
par une valeur par dfaut) ;
une mthode : la mthode ne peut pas tre redfinie par une classe
drive. Elle nest donc pas polymorphe ;
une classe : la classe ne peut pas tre spcialise. Elle naura donc aucun
descendant (aucune de ses mthodes nest donc polymorphe).
&
X. Crgut

Programmation objet en Java

221

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public class AttributsEtHeritage {


public static void main(String[] args) {
A a = new A();
B b = new B();
A c = new B();
System.out.println("a.attr1 = "
System.out.println("b.attr1 = "
System.out.println("a.attr2 = "
System.out.println("b.attr2 = "
System.out.println("b.attr2 = "
System.out.println("c.attr2 = "
System.out.println("((A) b).attr2 = "
}
}

+
+
+
+
+
+
+

a.attr1);
b.attr1);
a.attr2);
b.attr2);
b.attr2);
c.attr2);
((A) b).attr2);

class A {
int attr1 = 1;
int attr2 = 2;
}
class B extends A {
int attr2 = 4;
}

&
X. Crgut

Attributs, hritage et liaison dynamique

Programmation objet en Java

222

'

Rsultats de lexcution
1
2
3
4
5
6
7

a.attr1 = 1
b.attr1 = 1
a.attr2 = 2
b.attr2 = 4
b.attr2 = 4
c.attr2 = 2
((A) b).attr2 = 2

Rgles :
Il ny a pas de redfinition possible des attributs, seulement du masquage.
Lattribut est slectionn en fonction du type apparant de lexpression.
Conseil : viter de donner un attribut un nom utilis dans sa super-classe.
Remarque : Comme les attributs ne doivent pas tre publics, gnralement
le problme ne se pose pas.
&

X. Crgut

Programmation objet en Java

223

'

La classe Object

En Java, si une classe na pas de classe parente, elle hrite implicitement de


la classe Object. Cest lanctre commun toutes les classes.
Elle contient en particulier les mthodes :
public boolean equals(Object obj); galit logique de this et obj.
Attention, limplantation par dfaut utilise == (galit physique).
public String toString(); chane de caractres dcrivant lobjet. Elle est
utilise dans print, println et loprateur de concatnation + par
lintermdiaire de String.valueOf(Object).
protected void finalize(); Mthode appele lorsque le ramasse-miettes
rcupre la mmoire dun objet.
...
Voir le transparent T. 374 pour dautres caractristiques de la classe Object.

&
X. Crgut

Programmation objet en Java

224

'

Classe abstraite : exemple introductif


Exercice 27 tant donnes les classes Point, PointNomm, Segment,
Cercle... on souhaite formaliser la notion de dessin.
27.1 Comment peut-on modliser cette notion de dessin en Java ?
27.2 Comment faire pour afficher ou translater un tel dessin ?
27.3 Comment faire si on veut ajouter un Polygone ?
27.4 Comment faire si on veut pouvoir agrandir (effet zoom) le dessin ?

&

X. Crgut

Programmation objet en Java

225

'

Mthode retarde

Dfinition : Une mthode retarde (ou abstraite) est une mthode dont on
ne sait pas crire le code. Cette mthode est note abstract (modifieur).
Exemple : Un objet gomtrique peut tre affich et dplac mais si on ne
connat pas le type dobjet, on ne sait pas crire le code de ces mthodes
/** Afficher les caractristiques de lobjet gomtrique. */
abstract public void afficher();
/** Translater lobjet.
* @param dx dplacement suivant laxe des X
* @param dy dplacement suivant laxe des Y */
abstract public void translater(double dx, double dy);

Remarque : On ne met pas daccolades aprs une mthode retarde !


Attention : abstract est incompatible avec final ou static : une mthode
retarde est ncessairement une mthode dinstance polymorphe !

&

X. Crgut

Programmation objet en Java

226

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Classe abstraite : la classe ObjetGomtrique

/** Modlisation de la notion dobjet gomtrique. */


abstract public class ObjetGomtrique {
private java.awt.Color couleur;
// couleur de lobjet
/** Construire un objet gomtrique.
* @param c la couleur de lobjet gomtrique */
public ObjetGomtrique(java.awt.Color c)
{ this.couleur = c; }
/** Obtenir la couleur de cet objet.
* @return la couleur de cet objet */
public java.awt.Color getCouleur()
/** Changer la couleur de cet objet.
* @param c nouvelle couleur */
public void setCouleur(java.awt.Color c)

{ return this.couleur; }

{ this.couleur = c; }

/** Afficher sur le terminal les caractristiques de lobjet.


abstract public void afficher();

&
X. Crgut

/** Translater lobjet gomtrique.


* @param dx dplacement en X
* @param dy dplacement en Y */
abstract public void translater(double dx, double dy);

Programmation objet en Java

*/

227

'

ObjetGomtrique
couleur: Couleur
+getCouleur(): Couleur
+setCouleur(nc; Couleur)
+afficher()
+translater(dx: double, dy: double)
+constructeur ObjetGomtrique(c: Couleur)

Point
x: double
y: double

extrmit1

Segment

1
+translater(dx: double, dy: double)
+afficher()
+distance(autre: Point): double
+getX(): double
+getY(): double
+setX(nx: double)
+setY(ny: double)
+constructor Point(vx: double, vy: double)

extrmit2
1

getLongueur(): double
+translater(dx: double, dy: double)
+afficher()
+constructor Segment(e1: Point, e2: Point)

PointNomm
nom: String

&
X. Crgut

+getNom(): String
+setNom(n: String)
+afficher()
+constructor PointNomm(vx: double, vy: double, n: String)

Programmation objet en Java

228

'

Commentaires sur la notation UML

Essayer de placer les classes parentes au-dessus des sous-classes.


Ne pas confondre la relation de gnralisation/spcialisation avec une
relation dassociation avec sens de navigation !
Le nom des classes abstraites et des mthodes retardes est not en
italique... Ce qui nest pas toujours trs visible !
Remarque : On peut galement utiliser la contrainte {abstract}.
Dans une sous-classe UML, on ne fait apparatre que les mthodes qui
sont dfinies ou redfinies dans la sous-classe.
Exemples : Point dfinit afficher et translater qui taient spcifies dans
ObjetGomtrique.
Dans PointNomm on ne fait apparatre ni translater ni distance car ce sont
celles de Point. En revanche, afficher est redfinie.
La relation entre Segment et Point est une relation de composition.
Comment la raliser en Java ?
&

X. Crgut

Programmation objet en Java

229

'

Classe abstraite

Dfinition : Une classe abstraite est une classe dont on ne peut pas crer
dinstance (abstract class).
Remarque : Une classe qui possde une mthode retarde (propre ou
hrite) est ncessairement une classe abstraite.
Consquence : Une classe abstraite ne pouvant pas tre instancie, elle
devra donc avoir des descendants qui dfinissent les mthodes retardes.
Remarque : Une classe peut tre dclare abstraite mme si toutes ses
mthodes sont dfinies.
Constructeurs : Une classe abstraite peut avoir des constructeurs et il est
recommand den dfinir (sils ont un sens).
Exercice 28 Quel est lintrt dutiliser une mthode retarde plutt que de
dfinir une mthode avec un code vide (ou affichant un message derreur)
qui serait redfinie dans les sous-classes ?
&

X. Crgut

Programmation objet en Java

230

'

Intrt des classes abstraites

Factoriser le comportement de plusieurs classes mme si on nest pas


capable de le coder compltement. Ce comportement peut alors tre
utilis.
Exercice 29 Dfinir une classe Groupe (dobjets gomtriques). Groupe
est-elle abstraite ? Peut-on mettre un Groupe dans un Groupe ?
Classifier les objets, par exemple les objets gomtriques gnraux,
ferms, ouverts, etc.
Permettre au compilateur de vrifier que la dfinition des mthodes
retardes hrites est bien donne dans les sous-classes.
Remarque : Une sous-classe dune classe abstraite peut tre concrte ou
abstraite suivant quelle donne ou non une dfinition toutes ses mthodes
(propres et hrites).
Exercice 30 Dfinir un menu textuel.
&
X. Crgut

Programmation objet en Java

231

'

Hritage multiple

Dfinition : On dit quil a hritage multiple si une classe hrite dau moins
deux classes (parentes).
VHICULE

Exemple : Un mobilehome et un hydravion.


VEHICULE

MAISON
AVION

BATEAU

MOBILEHOME

HYDRAVION

hritage multiple

hritage rpt

Problmes poss : Que deviennent les attributs et mthodes prsents dans


les deux classes parentes ? Reprsentent-ils la mme notion (fusion) ou des
notions diffrentes (duplication).
Solution propose par Java : Interdire lhritage multiple et introduire la
notion dinterface.
&

X. Crgut

Programmation objet en Java

232

'

Exercice 31
31.1 Comment faire pour crire une mthode de tri dun tableau qui soit
gnrale ?
31.2 Comment faire pour crire une mthode permettant de dessiner sur
un cran graphique tous les lments dun tableau ?
31.3 Comment faire pour quun objet, un point par exemple, puisse
apparatre la fois comme lment du premier tableau et du deuxime
tableau ?

&

X. Crgut

Programmation objet en Java

233

'

Interfaces et hritage

Hritage multiple : Une interface peut spcialiser plusieurs interfaces.


interface I extends I1, I2 { ...

Attention : Deux mthodes ayant mme nom et mme signature sont


considres comme la mme mthode.
= Cest une rsolution syntaxique du pb de lhritage multiple :-(
public interface Affichable {
/** Afficher avec un dcalage de indentation espaces. */
void afficher(int indentation);
}
public interface MultiAffichable {
/* Afficher plusieurs fois. */
void afficher(int nb);
}
public class PbHeritageInterface implements Affichable, MultiAffichable {
public void afficher(int entier) { // Que signifie afficher ?
System.out.println("Entier = " + entier);
}
}

&

X. Crgut

Programmation objet en Java

234

'

Interface vs Classe abstraite

Les classes abstraites ont pour avantage de pouvoir contenir un


comportement partiellement dfini (des attributs et le code de mthodes).
/** Comparer des objets avec une relation dordre total */
public abstract class OrdreTotal<T> {
/** Strictement infrieur (lesser than) */
public abstract boolean lt(T a);
/** Suprieur ou gal (greater equal) */
final public boolean ge(T a)
{ return !this.lt(a); }
/** Strictement suprieur (greater than) */
final public boolean gt(T a)
{ return a.lt(this); }
/** Infrieur ou gal (lesser equal) */
final public boolean le(T a)
{ return !a.lt(this); }
final public boolean equals(T a)
{ return !this.lt(a) && !a.lt(this); }
}

Attention : La liaison tardive fait que a < b b > a peut tre faux.
&
X. Crgut

Programmation objet en Java

235

'

Interface vs Classe abstraite (suite)

La classe OrdreTotal permet de dfinir, partir dune mthode de


comparaison, les autres mthodes usuelles. Malheureusement, si une classe
hrite de OrdreTotal, elle ne pourra pas hriter dune autre classe.
Pour transformer la classe abstraite en interface, il faut supprimer le code de
toutes les mthodes. Il est alors prfrable de les supprimer directement.
On arrive ainsi linterface Comparable de lAPI Java :
interface Comparable {
/** Comparer cet objet avec lobjet spcifi. Le rsultat est ngatif,
* nul ou positif suivant que this est <, = ou > lobjet spcifi */
public int compareTo(Object o);
}

Attention : La documentation de Comparable recommande que compareTo


soit cohrent avec equals mais ceci ne peut pas tre forc comme dans le cas
de OrdreTotal.
&

X. Crgut

Programmation objet en Java

236

'

Contraintes sur la (re)dfinition

Respect de la smantique : La redfinition dune mthode doit prserver la


smantique de la version prcdente : la nouvelle version doit fonctionner
au moins dans les mmes cas et faire au moins ce qui tait fait (cf T. 314).
Preuve : Une mthode f(B b, ...) travaille sur une classe polymorphe B.
Cette classe B contient au moins une mthode polymorphe g.
Lauteur de f ne connat que B (a priori). Il utilise donc la spcification de
B pour savoir comment appeler g et ce quelle fait.
En fait, la mthode f est appele avec un objet de la classe A drive de B
(principe de substitution) et redfinissant g.
En raison de la liaison tardive, cest donc la version de g de la classe
drive A qui est appele.
Conclusion : la version de g dans A doit fonctionner dans les cas prvus
dans la super-classe B et faire au moins ce qui tait prvu dans B.
Test : Une classe drive doit russir les tests de ses classes parentes.
&

X. Crgut

Programmation objet en Java

237

'

Constructeur et mthode polymorphe


Rgle : Un constructeur ne devrait pas appeler de mthode polymorphe.
Preuve : Considrons une classe A dont lun de ses constructeurs utilise une
mthode polymorphe m.
Puisque m est une mthode polymorphe, elle peut tre redfinie dans une
classe B sous-classe de A.
La redfinition de m dans B peut utiliser un attribut de type objet attr
ajout dans B (donc non prsent dans A).
Lordre dinitialisation des constructeurs fait que le constructeur de A est
excut avant celui de B, donc attr est null. Or le constructeur de A
excute m, donc la version de B (liaison tardive) qui utilise attr non encore
initialis !
&
X. Crgut

Programmation objet en Java

238

'

Rutilisation

La rutilisation se fait en Java au travers des classes.


Il sagit de rutiliser des classes dj crites.
Il y a deux possibilits pour quune classe A rutilise une classe B :
la relation dutilisation (association, agrgation ou composition) :
class A {
B b;
...
}

// poigne sur un objet de B

Exemple : La classe segment (r)utilise la classe Point.


la relation dhritage (spcialisation) :
class A extends B {
...
}

// A spcialise B

Exemple : La classe PointNomm (r)utilise la classe Point.


La question est alors : Quoi choisir entre utilisation et hritage ?
&
X. Crgut

Programmation objet en Java

239

'

Choisir entre hritage et utilisation

Rgles simples :
a = association (ou agrgation)
est compos de = composition (ou agrgation)
est un = hritage
Attention : est un ... et ... (utilisation) 6= est un ... ou ... (hritage)
Remarque : TRE, cest AVOIR un peu !
On peut toujours remplacer lhritage par lutilisation.
Linverse est faux. AVOIR, ce nest pas toujours TRE !
Deux rgles :
si on veut utiliser le polymorphisme = hritage
si on veut pouvoir changer dynamiquement le comportement des objets
= utilisation (poigne) associe lhritage
Exercice 32 Comment modliser une quipe de football ?

&
X. Crgut

Programmation objet en Java

240

'

Gnricit vs Hritage

Exercice 33
33.1 Quelles sont les relations entre une collection de points, une liste de
points et une liste chane de points ?
33.2 Quelles sont les relations entre une liste de points, une liste de
personnes, une liste de livres, etc.
33.3 Dfinir une pile de points (de capacit fixe).
33.4 Comment adapter la pile de points pour avoir une pile de livres ou
une pile de personnes ?
&

X. Crgut

Programmation objet en Java

241

'

Gnricit vs Hritage : schma

Vocabulaire : La gnricit sappelle galement polymorphisme


paramtrique : transformer un type en paramtre.
Le polymorphisme de la programmation par objet sappelle le
polymorphisme dhritage ou sous-typage.
&

X. Crgut

Programmation objet en Java

242

'

Gnricit vs Hritage : une pile fixe de points

/** Une pile de points


* de capacit fixe. */
public class PileFixePoint {
private Point[] lments;
private int nb;

public Point getSommet() {


return lments[nb-1];
}

public void empiler(Point elt) {


lments[nb++] = elt;
public PileFixePoint(int capacit) { }
lments = new Point[capacit];
nb = 0;
public void dpiler() {
}
nb--;
lments[nb] = null;
public boolean estVide() {
}
return nb == 0;
}
}

Attention : On ne fait aucun contrle sur la validit des oprations (empiler,


dpiler, sommet) : voir chapitre Responsabilits dune classe (T. 262).
&
X. Crgut

Programmation objet en Java

243

'

Gnricit vs Hritage : utilisation de PileFixePoint


class TestPileFixePoint {
public static void main (String args []) {
PileFixePoint pile = new PileFixePoint(10);
for (int i = 0; i < 10; i++) {
pile.empiler(new Point(i, i));
}
while (!pile.estVide()) {
pile.getSommet().afficher();
pile.dpiler();
}
}
}

Quelles sont les vrifications que peut faire le compilateur ?


Quelles sont les vrifications qui ne peuvent tre ralises qu
lexcution ?

&

X. Crgut

Programmation objet en Java

244

'

Une pile fixe gnrale : polymorphisme dhritage

/** Une pile de capacit fixe gnrale :


public Object getSommet() {
* polymorphisme dhritage */
return lments[nb-1];
public class PileFixeObject {
}
private Object[] lments;
private int nb;
public void empiler(Object elt) {
lments[nb++] = elt;
public PileFixeObject(int capacit) { }
lments = new Object[capacit];
nb = 0;
public void dpiler() {
}
nb--;
lments[nb] = null;
public boolean estVide() {
}
return nb == 0;
}
}

Attention : On ne fait aucun contrle sur la validit des oprations (empiler,


dpiler, sommet) : voir chapitre Responsabilits dune classe (T. 262).
&
X. Crgut

Programmation objet en Java

245

'

Gnricit vs Hritage : utilisation de PileFixeObject


class TestPileFixeObject {
public static void main (String args []) {
PileFixeObject pile = new PileFixeObject(10);
for (int i = 0; i < 10; i++) {
pile.empiler(new Point(i, i));
}
while (!pile.estVide()) {
((Point)pile.getSommet()).afficher();
pile.dpiler();
}
}
}

Quelles sont les vrifications que peut faire le compilateur ?


Quelles sont les vrifications qui ne peuvent tre ralises qu
lexcution ?

&

X. Crgut

Programmation objet en Java

246

'

Une pile fixe gnrale : gnricit


}

/** Une pile de capacit fixe :


* gnricit */
public class PileFixe<G> {
// G : paramtre gnrique

public G getSommet() {
return lments[nb-1];
}

private G[] lments;


private int nb;

public void empiler(G elt) {


lments[nb++] = elt;
}

public PileFixe(int capacit) {


lments = new G[capacit];
nb = 0;
}
public boolean estVide() {
return nb == 0;

public void dpiler() {


nb--;
lments[nb] = null;
}
}

Attention : On ne fait aucun contrle sur la validit des oprations (empiler,


dpiler, sommet) : voir chapitre Responsabilits dune classe (T. 262).
&
X. Crgut

Programmation objet en Java

247

'

Gnricit vs Hritage : utilisation de PileFixe

class TestPileFixe {
public static void main (String args []) {
PileFixe<Point> pile = new PileFixe<Point>(10);
// instanciation du paramtre gnrique
for (int i = 0; i < 10; i++) {
pile.empiler(new Point(i, i));
}
while (!pile.estVide()) {
pile.getSommet().afficher();
pile.dpiler();
}
}
}

Quelles sont les vrifications que peut faire le compilateur ?


Quelles sont les vrifications qui ne peuvent tre ralises qu
lexcution ?

&
X. Crgut

Programmation objet en Java

248

'

Gnricit vs Hritage : conclusions

Utiliser lhritage pour simuler la gnricit, cest masquer les types


apparents par un type plus gnral (Object).
Ceci comporte plusieurs inconvnients :
Le compilateur ne peut pas faire de contrle (utile) de types. Il est
possible de mettre nimporte quel type dobjet dans la pile !
Le programmeur doit faire du transtypage quand il rcupre les objets
(contrl lexcution seulement, donc trop tard !).
Les informations de type ne sont pas apparentes dans le source et doivent
tre remplaces par des commentaires : comment dclarer une pile de
points ? Et une pile dobjets gomtriques ?
Conclusion : Lhritage permet de simuler la gnricit mais au dtriment
des contrles qui peuvent tre faits par le compilateur. Le programmeur doit
tre plus vigilent. Heureusement, Java 1.5 apporte la gnricit !

&
X. Crgut

Programmation objet en Java

249

'

Que faire si on ne dispose pas de la gnricit ?

On peut allier polymorphisme dhritage et contrle de type en crivant


autant de classes enveloppes que dinstanciations possibles.
}

/** Une pile fixe de points


* en utilisant PileFixeObject
* mais avec contrle de type. */
public class PileFixePoint {

public Point getSommet() {


return (Point) points.getSommet();
}

private PileFixeObject points;

public void empiler(Point elt) {


points.empiler(elt);
}

public PileFixePoint(int capa) {


points =
new PileFixeObject(capa);
}
public boolean estVide() {
return points.estVide();

public void dpiler() {


points.dpiler();
}
}

Remarque : Cest ce quengendre automatiquement le compilateur de java


1.5 !
&
X. Crgut

Programmation objet en Java

250

'

Consquences
Dun point du vue pratique, il nexiste quune seule classe, par exemple
Pile et non Pile<String>, Pile<Point>... (diffrent de C++).
Si G est une classe Gnrique et A et B deux types, G<A> et G<B> ont mme
classe G. Linformation de gnricit a disparu.
Le compilateur engendre donc les transtypages ncessaires.
Les informations de types sont uniquement connues du compilateur et
non de la JVM. Dans le byte code, les informations de gnricit ont
disparu !
On ne peut pas utiliser instanceof ni faire du transtypage avec un type
gnrique.
&

X. Crgut

Programmation objet en Java

251

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

public class TestErreurTranstypage {


public static void main(String[] args) {
Paire<String, Integer> pp = new Paire<String, Integer>("I", 1);
Paire po = pp;
Object o = pp;
Paire<Integer, String> p2 = null;
p2 = po;
// unchecked conversion
p2 = (Paire) po;
// unchecked conversion
p2 = (Paire<Integer, String>) po; // unchecked cast
String str = p2.second;
// ClassCastException !
p2 = o;
// incompatible types
p2 = (Paire) o;
// unchecked conversion
p2 = (Paire<Integer, String>) o; // unchecked cast
Paire<Integer, String> ps = (Paire<Integer, String>) pp;
// inconvertible types
// Le compilateur connat le type de pp et peut vrifier !
assert po instanceof Paire<String, Integer>;
// illegal generic type for instanceof
assert po instanceof Paire;

&
X. Crgut

Programmation objet en Java

252

'

Gnricit et sous-typage
Exercice 34 Y a-t-il une relation de sous-typage entre ListeTab<Object> et
ListeTab<String> ? Dans quel sens ?

&
X. Crgut

Programmation objet en Java

253

'
1
2
3
4
5
6
7
8
9
10

Gnricit et sous-typage

public class TestErreurGenericiteSousTypage {


public static void main(String[] args) {
ListeTab<String> ls = new ListeTab<String> (10);
ListeTab<Object> lo = ls;
lo.ajouter(0, "texte");
lo.ajouter(0, 15.5);
// en fait new Double(15.5);
String s = ls.item(0);
System.out.println(s);
}
}
TestErreurGenericiteSousTypage.java:4: incompatible types
found
: ListeTab<java.lang.String>
required: ListeTab<java.lang.Object>
ListeTab<Object> lo = ls;
^
Note: ./ListeTab.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Remarque : Il y aurait une relation de sous-typage si ListeTab tait


immuable !
&
X. Crgut

Programmation objet en Java

254

'

Exercice 35 On considre la mthode afficher et le programme de test


ci-dessous.

/** Afficher tous les lments de ll. */


static public void afficher(Liste<Object> ll) {
for (int i = 0; i < ll.taille(); i++) {
System.out.println(ll.item(i));
}
}
public static void main(String[] args) {
Liste<Object> lo = new ListeTab<Object> (5);
lo.ajouter(0, "deux");
lo.ajouter(0, "un");
afficher(lo);
Liste<String> ls = new ListeTab<String> (5);
ls.ajouter(0, "deux");
ls.ajouter(0, "un");
afficher(ls);
}

35.1 Que donnent la compilation et lexcution de ce programme ?


35.2 Proposer une nouvelle version de la mthode afficher.
&
X. Crgut

Programmation objet en Java

255

'

Utilisation du type joker

Erreur de compilation : Liste<String> nest pas un sous-type de


Liste<Object> ! Voir T. 253.
Une solution consisterait utiliser une mthode gnrique :
static public <T> void afficher(Liste<T> ll) {
for (int i = 0; i < ll.taille(); i++) {
System.out.println(ll.item(i));
}
}

Une meilleure solution consiste utiliser un type joker (wildcard) : <?> :


static void afficher(Liste<?> ll) {
for (int i = 0; i < ll.taille(); i++) {
System.out.println(ll.item(i));
}
}
Liste<?>

est appele liste dinconnus . Le type nest pas connu !

Cette solution est meilleure car T ntait jamais utilis (ne servait rien).
Rq : On peut utiliser des types joker contraints (<?
&
X. Crgut

Programmation objet en Java

extends Type>).

256

'

Limite des types joker


/** Copier les lments de source dans la liste destination. */
public static void copier(Liste<?> destination, Object[] source) {
for (Object o : source) {
destination.ajouter(destination.taille(), o);
}
}

Le compilateur interdit dajouter un objet dans une liste dinconnus !


La solution consiste prendre un paramtre de gnricit :
public static <T> void copier(Liste<T> destination, T[] source) {
for (T o : source) {
destination.ajouter(destination.taille(), o);
}
}

Que donnent alors les instructions suivantes ?


String[] tab = { "un", "deux" };
copier(new ListeTab<Object> (2), tab);

Exercice 36 crire une mthode de classe qui copie une liste dans une
autre.
&
X. Crgut

Programmation objet en Java

257

'

Tableau et sous-typage

Exercice 37 Que donnent la compilation et lexcution de ce programme ?


Comment ladapter pour fonctionner sur des listes ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

public class TableauxSousTypage {


public static void copier(Object[] destination, Object[] source) {
assert destination.length >= source.length
: "Capacit insuffisante : " + destination.length
+ " < " + source.length;
for (int i = 0; i < source.length; i++) {
destination[i] = source[i];
}
}
public static void main(String[] args) {
String[] tab1 = { "un", "deux", "trois" };
String[] tab2 = new String[tab1.length];
copier(tab2, tab1);
Object[] tab3 = { "un", "deux", new Integer(3) };
copier(tab2, tab3);

&

X. Crgut

Programmation objet en Java

258

'

Tableau et sous-typage : hritage du pass !


Compilation : OK
Cest surprenant et peu logique daprs T. 253.
Rsultats de lexcution :
1
2
3

Exception in thread "main" java.lang.ArrayStoreException:


java.lang.Integer
at TableauxSousTypage.copier(TableauxSousTypage.java:7)
at TableauxSousTypage.main(TableauxSousTypage.java:17)

Consquences :
Si B est un sous-type de A, alors B[] est un sous-type de A[].
Justification : compatibilit ascendante !
Typage incomplet = erreur dtecte lexcution (ArrayStoreException)
&

X. Crgut

Programmation objet en Java

259

'

Et avec les listes ?

Premire solution ?
public static <T> void copier(Liste<T> destination, Liste<T> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}

Problme : Peut-on ajouter une liste de PointNomm une liste de


Point ?
Deuxime solution ?
public static <T1, T2>
void copier(Liste<T1> destination, Liste<T2> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}

Et non !
&

X. Crgut

Programmation objet en Java

260

'

Et avec les listes ? (suite)

Solution : Dire quil y a une relation de sous-typage entre les deux types
public static <T1, T2 extends T1>
void copier(Liste<T1> destination, Liste<T2> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}

Contrainte sur T2
Solution plus gnrale :
public static <T>
void copier(Liste<? super T> destination, Liste<? extend T> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}

Plus gnral : Le premier joker est tout super type de T.


Utile si plusieurs destinations, ou un autre paramtre de type T.
&

X. Crgut

Programmation objet en Java

261

'

Responsabilits dune classe


Motivation : Un problme important dans le dveloppement de logiciels
est de savoir qui est responsable de quoi : dfinition des responsabilits.
Cest le problme que nous abordons ici.
Plan de la partie :
Exemple introductif : les fractions
Responsabilits de la classe Fraction
Principe de protection en criture des attributs
Programmation dfensive et exceptions
Programmation par contrat
Conclusions

&

X. Crgut

Programmation objet en Java

262

'

Exemple : les fractions

Soit une classe Fraction dfinie par son numrateur et son dnominateur :
public class Fraction {
public int numrateur;
public int dnominateur;
public Fraction(int num, int dn)
public void normaliser() { ... }
...
}

{ ... }

Est-il utile de normaliser la reprsentation dune fraction ? Pourquoi ?


Qui doit utiliser normaliser ?
Peut-on crer une Fraction(-4, -12) ?
Peut-on toujours calculer linverse dune Fraction ? Comment est-on
averti si une opration nest pas possible ?
Quels sont les avantages/inconvnients de pouvoir accder aux attributs
numrateur et dnominateur ?

&

X. Crgut

Programmation objet en Java

263

'

Responsabilits de la classe Fraction


Dfinition : Les responsabilits dune classe dcrivent ce quoi elle
sengage au moyen :
dinvariants : ils lient les requtes (indirectement ltat interne de
lobjet). Un invariant doit toujours tre vrifi par tous les objets ;
dobligations : elles dcrivent les mthodes de la classe.
Invariant de la classe Fraction : Une fraction est toujours normalise.
Le dnominateur est strictement positif.
Le numrateur et le dnominateur sont rduits.
La fraction nulle est reprsente par 0/1.
Obligations de la classe Fraction :
Linverse na de sens que pour une fraction non nulle.
etc.

&

X. Crgut

Programmation objet en Java

264

'

Principe de protection en criture des attributs


Principe : Les attributs ne doivent pas tre publics.
Justification : Si une classe donne accs en criture un attribut, elle ne
peut plus garantir la cohrence de ses objets (invariants).
Consquence : Dfinir des mthodes daccs et des mthodes daltration.
Les mthodes daltration contrlent la cohrence de la modification.
En Java :
Dclarer les attributs private ;
Dfinir une mthode daccs (si lattribut fait partie des requtes) ;
Dfinir une mthode de modification (si dans les commandes).
Remarque : Pour des raisons de simplicit, nous ne dfinirons les
modifieurs et accesseurs que dans le cas o ils sont public.
&

X. Crgut

Programmation objet en Java

265

'

Fraction et principe de protection en criture des attributs


public class Fraction {
private int numrateur;
private int dnominateur;
public Fraction(int num, int dn)
public int getNumrateur()
public int getDnominateur()
public void set(int n, int d)
public void set(int n)
...
}

{
{
{
{
{

set(num, dn); }
return numrateur; }
return dnominateur; }
... }
set(n, 1); }

Remarques :
Les deux attributs sont private ;
Chaque attribut possde son accesseur ;
Les modificateurs individuels des attributs ne sont pas dfinis. Ils auraient
pu tre dfinies comme protected.
Notation : La convention Java est de prfixer le nom de lattribut par
get et le modifieur par set .
&
X. Crgut

Programmation objet en Java

266

'

Programmation dfensive

Principe : Les cas anormaux sont tests dans le sous-programme.


Traitements possibles :
signaler un message derreur et continuer lexcution ;
signaler un message derreur et arrter lexcution ;
renvoyer un code derreur ;
particulariser une valeur de retour pour indiquer lerreur ;
raliser un traitement par dfaut (renvoyer une valeur valide) ;
appeler une fonction fournie par lappelant ;
Questions :
Qui dtecte lerreur (ou le problme) ?
Qui est capable de le rsoudre ?
Meilleure solution : Signaler lerreur en levant une exception.

&

X. Crgut

Programmation objet en Java

267

'

Exceptions

Exemple introductif
Intrt des exceptions
Classification des exceptions en Java
Mcanisme des exceptions
Les exceptions utilisateur
Exemples dutilisation des exceptions
Une exception est une classe
Conseils sur lutilisation des exceptions

&

X. Crgut

Programmation objet en Java

268

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

import java.io.*;
// io pour input/output
public class Moyenne {
/** Afficher la moyenne des valeurs relles du fichier args[0] */
public static void main (String args []) {
try {
BufferedReader in = new BufferedReader(new FileReader(args[0]));
int nb = 0;
// nb de valeurs lues
double somme = 0; // somme des valeurs lues
String ligne;
// une ligne du fichier
while ((ligne = in.readLine()) != null) {
somme += Double.parseDouble(ligne);
nb++;
}
in.close();
System.out.println("Moyenne = " + (somme / nb));
} catch (IOException e) {
System.out.println("Problme dE/S : " + e);
e.printStackTrace();
} catch (NumberFormatException e) {
System.out.println("Une donne non numrique : " + e);
}
}
}

&

X. Crgut

Exceptions : Exemple dmonstratif

Programmation objet en Java

269

'

Exceptions : Exemples dutilisation de Moyenne

> java Moyenne Donnes1


Moyenne = 15

# excution nominale (10 15 20)

> java Moyenne Donnes2


# (10 15 20 quinze)
Une donne non numrique : java.lang.NumberFormatException: quinze
> java Moyenne
# pas de fichier en argument
Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException
at Moyenne.main(Moyenne.java:6)
> java Moyenne Donnes4
# fichier contenant des lignes vides
Une donne non numrique : java.lang.NumberFormatException: empty String
> java Moyenne Donnes5
# fichier inexistant
Problme dE/S : java.io.FileNotFoundException: Donnes5 (Aucun fichier
ou rpertoire de ce type)
java.io.FileNotFoundException: Donnes5 (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at java.io.FileReader.<init>(FileReader.java:41)
at Moyenne.main(Moyenne.java:6)
> java Moyenne Donnes3
Moyenne = NaN

&

X. Crgut

# pas de valeur dans le fichier

Programmation objet en Java

270

'

Exceptions : Intrts
Les exceptions permettent :
de transfrer le flot de contrle de linstruction qui lve lexception (qui
dtecte lanomalie) vers la partie du programme capable de la traiter ;
dviter de surcharger le code dune mthode avec de nombreux tests
concernant des cas anormaux ;
de regrouper le traitement des cas anormaux et erreurs ;
de diffrencier les anomalies (diffrents types dexception) ;
Remarque : Les exceptions peuvent tre considres comme des goto
disciplins.
Attention : Il ne faut pas abuser des exceptions et les rserver aux cas
rellement anormaux ou derreurs.
&

X. Crgut

Programmation objet en Java

271

'

Exceptions : Principe

Motivation : Mcanisme pour le traitement des erreurs et/ou des cas


anormaux.
Principe : Le mcanisme repose sur trois phases :
une exception est leve quand une erreur ou anomalie est dtecte ;
lexception est propage : lexcution squentielle du programme est
interrompue et le flot de contrle est transfr aux gestionnaires
dexception ;
Lexception est (ventuellement) rcupre par un gestionnaire
dexception. Elle est traite et lexcution normale reprend avec les
instructions qui suivent le gestionnaire dexception.
Remarque : Une exception non rcupre provoque larrt du programme
(avec affichage de la trace des appels de mthodes depuis linstruction qui a
lev lexception jusqu linstruction appelante de la mthode principale).

&

X. Crgut

Programmation objet en Java

272

'

Mcanisme de propagation dune exception


main

C1.m1(...)

C3.m3(...)

C2.m2(...)

C4.m4(...)

o1.m1(...)
o3.m3(...)
o2.m2(...)
Ex1
Exception
Instructions contrles par
les gestionnaires dexception

o4.m4(...)
Ex2
Ex3

gestionnaires dexception

instr
Ex4

instruction provoquant
la leve dune exception

Exercice 38 Indiquer la suite du programme lorsque instr lve Ex4, Ex3,


Ex1, Ex5 et Err.

&
X. Crgut

Programmation objet en Java

273

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Illustration du mcanisme de propagation

/** Illustrer le mcanisme de propagation des exceptions */


public class ExceptionPropagation {
public static void m1() {
m2();
}
public static void m2() {
m3();
}
public static void m3() {
int n = 1 / 0; // division par zro !
}
public static void main(String[] args) {
m1();
}
}

Exception in thread "main" java.lang.ArithmeticException: / by zero


at ExceptionPropagation.m3(ExceptionPropagation.java:10)
at ExceptionPropagation.m2(ExceptionPropagation.java:7)
at ExceptionPropagation.m1(ExceptionPropagation.java:4)
at ExceptionPropagation.main(ExceptionPropagation.java:13)

&

shell returned 1

X. Crgut

Programmation objet en Java

274

'

Hirarchie des exceptions en Java

Principe : Toutes les exceptions en Java hritent de la classe Throwable.


Voici un extrait de larbre dhritage.
Throwable
Exception

Error
VirtualMachineError
OutOfMemoryError

IOException

IndexOutOfBoundsException

FileNotFoundException

&
X. Crgut

RuntimeException
ArtithmeticException

IllegalArgumentException
NumberFormatException

Programmation objet en Java

275

'

Classification des exceptions

Les exceptions sont forcment drives de la classe Throwable.


En Java, les exceptions sont classes en deux catgories :
les exceptions hors contrle :
classes drives de java.lang.Error : ce sont des erreurs non
accessibles, qui ne peuvent gnralement pas tre rcupres
(OutOfMemoryError, AssertionError, NoClassDefFoundError...) ;
classes drives de java.lang.RuntimeException : ce sont des erreurs de
programmation ; elles ne devraient donc pas se produire
(NullPointerException, IndexOutOfBoundsException...) ;
les exceptions sous contrle. Ce sont les classes qui ne sont sous-types
ni de java.lang.Error ni java.lang.RuntimeException. Exemples :
java.io.IOException, Exception ou Throwable.
Le compilateur veut tre sr que le programmeur en a tenu compte.
Elles correspondent la notion de robustesse.
&

X. Crgut

Programmation objet en Java

276

'

La classe java.lang.Throwable

Throwable(String message)

cause de lexception ;
Throwable() : constructeur par dfaut (message == null) ;
Throwable(Throwable cause) : constructeur avec cause ;
Throwable(String message, Throwable cause) ;
printStackTrace() : afficher la trace des appels de mthodes ;
getMessage() : le message pass en paramtre du constructeur ;
getCause() : la cause de lexception ;
...

: constructeur avec un message expliquant la

Les classes java.lang.Exception et java.lang.Error

et Error najoutent aucune nouvelle caractristique. Elles


permettent simplement de classifier les anomalies.
Elles dfinissent des constructeurs de mme signature que Throwable.
&
X. Crgut

Exception

Programmation objet en Java

277

'

Extrait des descendants de java.lang.Error

java.lang.AssertionError
java.lang.LinkageError
+-- java.lang.ClassCircularityError
+-- java.lang.ClassFormatError
+-- java.lang.UnsupportedClassVersionError
+-- java.lang.ExceptionInInitializerError
+-- java.lang.IncompatibleClassChangeError
+-- java.lang.AbstractMethodError
+-- java.lang.IllegalAccessError
+-- java.lang.InstantiationError
+-- java.lang.NoSuchFieldError
+-- java.lang.NoSuchMethodError
+-- java.lang.NoClassDefFoundError
+-- java.lang.UnsatisfiedLinkError
+-- java.lang.VerifyError
java.lang.ThreadDeath
java.lang.VirtualMachineError
+-- java.lang.InternalError
+-- java.lang.OutOfMemoryError
+-- java.lang.StackOverflowError
+-- java.lang.UnknownError

&
X. Crgut

Programmation objet en Java

278

'

Extrait des descendants de java.lang.RuntimeException


java.lang.ArithmeticException
java.lang.ArrayStoreException
java.lang.ClassCastException
java.lang.IllegalArgumentException
+-- java.lang.IllegalThreadStateException
+-- java.lang.NumberFormatException
java.lang.IllegalMonitorStateException
java.lang.IllegalStateException
java.lang.IndexOutOfBoundsException
+-- java.lang.ArrayIndexOutOfBoundsException
+-- java.lang.StringIndexOutOfBoundsException
java.lang.NegativeArraySizeException
java.lang.NullPointerException
java.lang.SecurityException
java.lang.UnsupportedOperationException

&

X. Crgut

Programmation objet en Java

279

'

Extrait des autres descendants de Exception


java.lang.ClassNotFoundException
java.lang.CloneNotSupportedException
java.lang.IllegalAccessException
java.lang.InstantiationException
java.lang.InterruptedException
java.lang.NoSuchFieldException
java.lang.NoSuchMethodException
java.awt.AWTException
java.util.zip.DataFormatException
java.security.GeneralSecurityException
java.beans.IntrospectionException
java.io.IOException
org.xml.sax.SAXException
java.sql.SQLException
org.omg.CORBA.UserException

&
X. Crgut

Programmation objet en Java

280

'

Lever une exception

Loprateur throw permet de lever une exception. Une exception est une
instance dune classe descendant de Throwable (souvent de Exception).
Forme gnrale :
if (<condition anormale>) {
throw new TypeException(<paramtres effectifs>);
}

Exemples : En considrant la classe Fraction :


public Fraction(int num, int dn) {
if (dn == 0) {
throw new ArithmeticException("Division par zro");
}
...
}
public Fraction(Fraction autre) {
if (autre == null) {
throw new IllegalArgumentException("Poigne nulle");
}
...
}

&

X. Crgut

Programmation objet en Java

281

'
Le bloc try

Rcuprer une exception


{...}

peut tre suivi de plusieurs gestionnaires dexception :

catch (TypeExc1 e) {
// gestionnaire de lexception TypeExc1
// instructions excuter quand lexception TypeExc1 sest produite
} catch (TypeExc2 e) { // e paramtre formel (peu importe le nom)
// instructions excuter quand lexception TypeExc2 sest produite
} catch (Exception e) { // toutes les exceptions (utiles au programmeur)
// instructions excuter si une exception se produit
} catch (Throwable e) {
// Toutes les erreurs et autres ! Utile ?
}

Attention : Lordre des catch est important (principe de substitution).


Remarque : Aprs lexcution des instructions dun catch, lexcution
continue aprs le dernier catch (sauf si une exception est leve).
Conseil : Ne rcuprer une erreur que si vous savez comment la traiter (en
totalit ou partiellement).

&

X. Crgut

Programmation objet en Java

282

'

Traiter une exception

Si une exception est rcupre, cest que lon est capable de la traiter, au
moins partiellement. Ce traitement est fait dans les instructions du catch. Il
peut consister :
Rparer le problme et excuter de nouveau lopration (cf transparent
suivant)
Rtablir un tat cohrent et continuer lexcution sans recommencer
Calculer un autre rsultat remplaant celui de la mthode
Rparer localement le problme et propager lexception
catch (TypeException e) {
faire des choses;
// par exemple rtablir la cohrence de ltat
throw e;
// propager lexception
throw new ExcQuiVaBien(e);
// OU Chanage des exceptions (Java 1.4)
}

Rparer localement le problme et lever une nouvelle exception


Terminer le programme
&
X. Crgut

Programmation objet en Java

283

'

Traiter une exception : exemple du ressai


boolean reussi = false;
// est-ce que lopration a russi ?
do {
try {
instructions_qui_peuvent_chouer();
reussi = true; // ne sera excute que si aucune exception ne se
// produit dans instructions_qui_peuvent_chouer();
} catch (TypeExc1 e) {
traiter_TypeExc1(); // exemple : expliquer lerreur lutilisateur
} catch (TypeExc2 e) {
traiter_TypeExc2();
}
} while (! reussi);
// Les instructions ont t excutes sans erreurs !

Exercice 39 Adapter cet algorithme pour limiter le nombre de ressais 5.


&

X. Crgut

Programmation objet en Java

284

'

Exceptions : la clause finally


Un bloc finally peut tre mis aprs le dernier catch dun bloc try. Les
instructions du bloc finally seront toujours excutes quil y ait ou non une
exception leve, quelle soit rcupre ou non.
try {
instructions_qui_peuvent_chouer();
} catch (TypeExc1 e) {
traiter_TypeExc1();
} catch (TypeExc2 e) {
traiter_TypeExc2();
} finally {
instructions_toujours_excutes();
}

Intrt : tre sr de librer une ressource (faire un dispose sur un lment


graphique, fermer un fichier condition que louverture ait russi...).
&
X. Crgut

Programmation objet en Java

285

'

Documenter les exceptions : javadoc bien sr !

Ltiquette javadoc @throws signale que la mthode peut lever une exception.
Justification : Lappelant de la mthode connait ainsi les exceptions potentielles
exception = paramtre en sortie... gnralement non disponible.
Exemple : Spcification de la mthode java.util.Collection.remove(Object)
/**
* Removes a single instance of the specified element from this
* collection, if it is present (optional operation). More formally,
* removes an element <tt>e</tt> such that
* <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>, if
* this collection contains one or more such elements. Returns
* <tt>true</tt> if this collection contained the specified element (or
* equivalently, if this collection changed as a result of the call).
*
* @param o element to be removed from this collection, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the type of the specified element
is incompatible with this collection (optional)
*
* @throws NullPointerException if the specified element is null and this
collection does not permit null elements (optional)
*
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
is not supported by this collection
*
*/
boolean remove(Object o);

&
X. Crgut

Programmation objet en Java

286

'

Spcification des exceptions

Une exception correspond un rsultat transmis par une mthode.


Aussi, Java permet de spcifier les exceptions propages par une mthode.
Remarque : En fait, Java nimpose (et le compilateur ne vrifie) que la
spcification des exceptions sous contrle.
Syntaxe : Toutes les exceptions sous contrle qui sont (leves ou) propages
par une mthode doivent tre dclares en utilisant le mot-cl throws.
<modifieurs> Type maMthode(Type1 a) throws TypeExc1, TypeExc2 { ... }
public static double racineCarre(double x) throws MathException { ... }

Remarque : Le compilateur vrifie que toutes les exceptions


(sous-contrle) produites par les instructions du code de la mthode sont :
soit rcupres et traites par la mthode (clause catch) ;
soit dclares comme tant propages (clause throws).
&
X. Crgut

Programmation objet en Java

287

'

Spcification des exceptions : exemple


1
2
3
4
5
6
7

import java.io.FileReader;
class A {
void m1() {
FileReader f = new FileReader("info.txt");
}
}

Rsultat de la compilation
ExceptionSpecificationReader.java:5: unreported exception
java.io.FileNotFoundException; must be caught or declared to be
thrown
FileReader f = new FileReader("info.txt");
^
1 error

&

X. Crgut

Programmation objet en Java

288

'

Exceptions et sous-typage
Une mthode peut propager (donc lever) toute exception qui est :
une descendante de RuntimeException ou Error (throws implicite) ;
une descendante dune des exceptions listes dans la clause throws.
Exemple : Voir le transparent prcdent.
Remarque : Lhritage entre exceptions permet (principe de substitution) :
de limiter le nombre dexceptions dclarer (throws) ;
de rcuprer dans un mme catch plusieurs exceptions.
Attention : Dans les deux cas, on perd en prcision !
&

X. Crgut

Programmation objet en Java

289

'

Exceptions et redfinition de mthode

Rgle sur la redfinition de mthode : Une mthode redfinie ne peut lever que
des exceptions qui ont t spcifies par sa dclaration dans la classe parente.
= Elle ne peut donc pas lever de nouvelles exceptions (contrles).
class
class
class
class

1
2
3
4
5
6
7
8
9

E1
E2
E3
F1

extends
extends
extends
extends

Exception {}
E1 {}
E2 {}
Exception {}

class A {
void m() throws E2 { };
}

10
11
12
13
14
15
16
17
18

class B1
void
}
class B2
void
}
class B3
void
}

extends A {
m() throws E1 { };
extends A {
m() throws E3 { };
extends A {
m() throws F1 { };

ExceptionSpecificationRedefinition.java:11: m() in B1 cannot override m() in


A; overridden method does not throw E1
void m() throws E1 { };
^
ExceptionSpecificationRedefinition.java:17: m() in B3 cannot override m() in
A; overridden method does not throw F1
void m() throws F1 { };
^
2 errors

&

X. Crgut

Programmation objet en Java

290

'

Dfinition dune exception : exception utilisateur

Exception : Une exception est tout objet instance dune classe qui hrite de
Throwable. Cependant, une exception utilisateur hrite gnralement de
Exception ou de lune de ses descendantes.
Conseil : Choisir soigneusement la classe parente de son exception :
lexception doit-elle tre sous contrle ou hors contrle du compilateur ?
Dfinition type dune exception :
public class MathException extends Exception {
public MathException(String s) {
super(s);
}
public MathException() {
// utile ?
}
}

Remarque : Cette classe, comme toute autre, peut avoir des attributs et des
mthodes.
&

X. Crgut

Programmation objet en Java

291

'

Exemple dexception : la racine carre

public class RacineCarree {


public static double RC(double x) throws MathException {
if (x < 0) {
throw new MathException("Paramtre de RC strictement ngatif : " + x);
}
return Math.sqrt(x);
}
public static void main (String args []) {
try {
double d = Console.readDouble("Donnez un rel : ");
System.out.println("RC(" + d + ") = " + RC(d));
for (int i = 0; i < 10; i++) {
System.out.println("RC(" + i*i + ") = " + RC(i*i));
}
} catch (MathException e) {
System.out.println("Anomalie : " + e);
}
}
}

&

X. Crgut

Programmation objet en Java

292

'

Exemples dexceptions sur la classe Fraction

public class DivisionParZeroException extends Exception {


public DivisionParZeroException(String message) {
super(message);
}
}
public class Fraction {
private int numrateur;
private int dnominateur;
public Fraction(int num, int dn) throws DivisionParZeroException {
set(num, dn);
}
public void set(int n, int d) throws DivisionParZeroException {
if (d == 0) {
throw new DivisionParZeroException("Dnominateur nul");
}
...
}
public Fraction inverse() throws DivisionParZeroException {
return new Fraction(dnominateur, numrateur);
}
...
}

&
X. Crgut

Programmation objet en Java

293

'

Utilisation des exceptions de la classe Fraction

public class TestFractionExceptions {


public static void main (String args []) {
Fraction f;
try {
int n = Console.readInt("Numrateur : ");
int d = Console.readInt("Dnominateur : ");
f = new Fraction(n, d);
System.out.println("f = ");
f.afficher();
System.out.println("inverse de f = ");
f.inverse().afficher();
}
catch (DivisionParZeroException e) {
System.out.println("Le dnominateur dune fraction "
+ "ne doit pas tre nul");
// Est-ce un message correct ?
}
}
}

Exercice 40 Peut-on connatre, dans le gestionnaire dexception, la ligne


du bloc try qui est lorigine de lexception (cf commentaire) ?
&

X. Crgut

Programmation objet en Java

294

'

Une exception est une classe

Exercice 41 : Somme dentiers


Lobjectif est de calculer la somme des entiers donns en argument de la
ligne de commande en signalant les arguments incorrects. On indiquera le
caractre incorrect (qui nest donc pas un chiffre) et sa position dans
largument comme dans les exemples suivants :
java Somme 10 15 20
Somme : 45
java Somme 10 15.0 20.0
Caractre interdit : >.< la position 3 de 15.0

41.1 crire le programme qui ralise cette somme en signalant les erreurs
ventuelles.
41.2 Comment faire pour indiquer le numro de largument incorrect ?
41.3 Comment faire pour indiquer tous les arguments incorrects ?

&

X. Crgut

Programmation objet en Java

295

'

Le programme calculant la somme des arguments

/** Programme sommant les entiers en argument de la ligne de commande. */


class Somme {
public static void main (String args []) {
try {
int somme = 0;
for (int i = 0; i < args.length; i++) {
somme += Nombres.atoi(args[i]);
}
System.out.println("Somme : " + somme);
}
catch (FormatEntierException e) {
System.out.println("Caractre interdit : >"
+ e.getCaractereErrone()
+ "< la position " + e.getPositionErreur()
+ " de " + e.getChaine());
}
}
}

&

X. Crgut

Programmation objet en Java

296

'

Lexception FormatEntierException

/** Exception indiquant une reprsentation errone dun entier en base 10 */


public class FormatEntierException extends Exception {
private String chaine; // la chane contenant lentier en base 10
private int iErreur;
// indice de lerreur dans chaine
public FormatEntierException(String chaine, int indice) {
super("Caractre invalide");
this.chaine = chaine;
this.iErreur = indice;
}
/** La chane contenant lentier en base 10 */
public String getChaine() { return this.chaine; }
/** Position du premier caractre interdit (1 si cest le premier) */
public int getPositionErreur() { return this.iErreur + 1; }
/** Premier caractre erron. */
public char getCaractereErrone() { return this.chaine.charAt(this.iErreur); }
public String toString() {
return "FormatEntierException: Erreur dans " + this.chaine
+ " la position " + (this.iErreur+1);
}

&
}

X. Crgut

Programmation objet en Java

297

'

La mthode convertissant une chane en entier

/** Oprations sur les nombres */


public class Nombres {
/** Conversion de chane de caractres en entier naturel.
* @param s reprsentation dun entier naturel en base 10
* @return lentier correspondant s
* @exception FormatEntierException la chane est mal forme
*/
public static int atoi(String s) throws FormatEntierException {
int resultat = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 0 && c <= 9) {
resultat = resultat * 10 + (c - 0);
} else {
throw new FormatEntierException(s, i);
}
}
return resultat;
}
}

&
X. Crgut

Programmation objet en Java

298

'

Exceptions : quelques conseils

La gestion des exceptions nest pas suppose remplacer un test simple.


Ne pas faire une gestion ultrafine des exceptions : multiplier les blocs try
pnalise le programme en terme de performance.
Ne pas museler les exceptions.
try { beaucoup de code }
catch (Exception e) {}

Si le compilateur vous signale des exceptions sous contrle non gres


(ni rcupres, ni dclares comme propages), cest pour vous aider !
Lignorer en muselant les exceptions nenlve pas le problme.
viter dimbriquer les blocs try (faire des mthodes auxiliaires).
Ne pas avoir honte de propager une exception.
Si vous ntes pas capable de la traiter compltement, il est ncessaire de
la propager vers lappelant.

&
X. Crgut

Programmation objet en Java

299

'

Programmation par contrat : analogie avec le contrat

Dans le monde des affaires, un contrat est une spcification prcise


(lgalement non ambigu) qui dfinit les obligations et les bnfices des
(deux) parties prenantes.
obligations

bnfices

client

payer un mois lavance son voyage sans annulation possible

obtenir un tarif prfrentiel


pour le voyage

fournisseur

slectionner et rserver les htels,


avions, dans le budget dfini

faire des bnfices, mme si


le client ne part pas

Exemple trs simplifi : un client doit payer un certain montant (son


obligation) et son fournisseur lui rend un service (ralise un projet).
Programmation : Une mthode est le fournisseur, lappelant est le client.
&

X. Crgut

Programmation objet en Java

300

'

Programmation par contrat : Mise en uvre

Pour chaque mthode :


prconditions : obligation du programme appelant et bnfice de la
mthode. Cest le programme appelant qui doit les vrifier.
postconditions : bnfice pour lappelant et obligation pour la mthode.
Elles doivent tre remplies la fin de lexcution de la mthode (si ses
prconditions taient satisfaites).
Pour chaque classe :
invariants : dfinissent les proprits qui doivent toujours tre vrifies
par un objet de la classe (depuis sa construction jusqu sa destruction) en
particulier, (avant et) aprs lappel de chaque mthode.
Non respect dun contrat : Cest une erreur de programmation (du client
dans le cas dune prcondition, du fournisseur sinon) provoquant larrt du
programme ou, mieux, la leve dune exception ( ne pas rcuprer).

&

X. Crgut

Programmation objet en Java

301

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Programmation par contrat et racine carre

public class RacineCarree {


/** Racine carre. */
//@ requires x >= 0;
//@ ensures \result >= 0;
//@ ensures \result * \result == x;
public static double RC(double x) {
return Math.sqrt(x);
}

// x positif
// la racine carre est positive
// son carr est x

public static void main (String args []) {


double d = Console.readDouble("Donnez un rel : ");
if (d >= 0) {
// test explicite !!!
System.out.println("RC(" + d + ") = " + RC(d));
}
for (int i = 0; i < 10; i++) {
System.out.println("RC(" + i*i + ") = " + RC(i*i));
}
}
}

Remarque : Utiliser lgalit sur des rels est une erreur !


&
X. Crgut

Programmation objet en Java

302

'

Programmation par contrat : bnfices

Intrts :
dfinition des responsabilits : chacun sait qui fait quoi ;
documentation : les classes et mthodes sont documentes formellement
donc sans ambiguts ;
aide la mise au point (instrumentation du code avec les assertions) :
vrification dynamique des assertions ;
dtection des erreurs au plus tt (prs de leur origine) ;
exploitable par outils danalyse statique et gnrateurs de tests ;
code final optimis (non vrification des assertions).
Inconvnients : Les prconditions et surtout les postconditions sont
souvent difficiles identifier (compltude) et exprimer (rfrence ltat
prcdent, utilisation de quantificateurs existentiels et universels, etc.).
Exercice 42 Donner les contrats de la mthode pgcd.

&

X. Crgut

Programmation objet en Java

303

'

Programmation par contrat en pratique

La programmation par contrat existe :


Eiffel : compltement intgre au langage ;
UML : des strotypes sont dfinis invariant, precondition,
postcondition ainsi quun langage dexpression de contraintes OCL.
Java : envisage par les auteurs du langage mais non implante.
Java 1.4 introduit une clause assert (voir T. 315).
Elle est cependant accessible au travers dextensions telles que
iContract, jContractor, Jass... et surtout JML.
Mise en uvre avec JML
spcifier le comportement dans des commentaires /*@ ... @*/ et //@ ;
compiler en utilisant jmlc pour instrumenter les assertions ;
excuter avec jmlrac ;
engendrer la documentation avec jmldoc.
engendrer les programmes de test (jmlunit)
&

X. Crgut

Programmation objet en Java

304

'

JML : Java Modeling Language

JML : un langage de spcification du comportement introduisant


prconditions (requires), postconditions (ensures) et invariants (invariant).
Un contrat est exprim avec la syntaxe Java enrichie :
de limplication ==> (et <==) et de lquivalence <==> (et <=!=>).
a ==> b est quivalent (! a) || b
a <==> b (si et seulement si) est quivalent a == b

des quantificateurs universel (\forall) et existentiel (\exists).


(\forall dclarations; contraintes; expression boolenne)
(\forall int i; i >= 0 && i < tab.length; tab[i] > 0);
// tous les lments de tab sont strictement positifs
(\exists int i; i >= 0 && i < tab.length; tab[i] > 0);
// Il existe un lment de tab strictement positif

dautres quantificateurs \min, \max, \product, \sum.


(\sum int
(\max int
(\min int
(\product

&
X. Crgut

i; i >= -2 && i <= 1; i);


i; i > -2 && i < 3; i*i);
i; i > -2 && i < 3; i*i);
int i; i > 0 && i < 5; i);

//
//
//
//

Programmation objet en Java

-2, -2 + -1 +
4, max(-1*-1,
0, min(-1*-1,
24, 1 * 2 * 3

0 + 1
0*0, 1*1, 2*2)
0*0, 1*1, 2*2)
* 4 (= 4!)

305

'

JML : Extension pour les postconditions

Dans la postcondition (ensures) dune mthode m, on peut utiliser :


\result pour faire rfrence au rsultat de cette mthode m ;
//@ requires x != 0;
//@ ensures Math.abs(x * \result - 1) <= EPSILON;
//@ ensures Math.abs(inverse(\result) - x) <= EPSILON;
public static /*@ pure @*/ double inverse(double x) {
return 1.0 / x;
}

// prendre lun
// ou lautre

Remarque : On peut avoir un contrat rcursif.


\old(expr) : valeur de expr avant lexcution de cette mthode m ;
class Compteur {
private int valeur;
public /*@ pure @*/ int getValeur() {
return this.valeur;
}
//@ ensures getValeur() == \old(getValeur()) + 1;
public void incrementer() {
this.valeur++;
}
}

&
X. Crgut

Programmation objet en Java

306

'

JML : Contrats et droits daccs


Un contrat ne peut utiliser que des mthodes pures (sans effet de bord).
Justification : Lexcution du programme ne doit pas dpendre de leffet
dun contrat car les contrats peuvent tre (et seront) dsactivs.
Consquence : Utiliser /*@ pure @*/ avant le type de retour de la mthode
(car Java ne permet pas dexprimer une telle proprit).
Les invariants peuvent tre public ou private (choix de ralisation).
Remarque : Un invariant priv na pas de consquence sur lutilisateur de
la classe mais seulement sur limplmenteur.
Le contrat dune mthode ne peut utiliser que des mthodes ou attributs
de droits daccs au moins gaux ceux de cette mthode.
Justification : Lappelant doit pouvoir valuer le contrat.
&
X. Crgut

Programmation objet en Java

307

'

Programmation par contrat : la classe Fraction (1/4)

/** La classe Fraction reprsente les fractions rationnelles. */


public class Fraction {
//@public invariant Entier.pgcd(getNumerateur(),
//@
getDenominateur()) == 1;
//@public invariant getNumerateur() == 0 ==> getDenominateur() == 1;
//@public invariant getDenominateur() > 0;
private int num;
// le numrateur
private int den;
// le dnominateur
final public static Fraction UN = new Fraction(1);

// fraction unit

/** Initialiser une fraction.


* @param n le numrateur
* @param d le dnominateur (non nul !) */
//@ requires d != 0;
//@ ensures n * getDenominateur() == d * getNumerateur();
public Fraction(int n, int d)
{ set(n, d); }
/** initialiser une fraction partir dun entier (numrateur).
* @param n le numrateur */
//@ ensures n == getNumerateur();
//@ ensures 1 == getDenominateur();
public Fraction(int n)
{ this(n, 1); }

&

X. Crgut

Programmation objet en Java

308

'

Programmation par contrat : Fraction (2/4)

/** @return le numrateur de la fraction */


public /*@ pure @*/ int getNumerateur()
{ return num; }
/** @return le dnominateur de la fraction. */
//@ ensures getDenominateur() > 0;
public /*@ pure @*/ int getDenominateur()
{ return den; }
/** Modifier une fraction.
* @param n le nouveau numrateur
* @param d le nouveau dnominateur (non nul !)
*/
//@ requires d != 0;
//@ ensures n * getDenominateur() == d * getNumerateur();
public void set(int n, int d) {
num = n;
den = d;
normaliser();
}
/** normaliser la fraction. */
private void normaliser()

&
X. Crgut

{ ... }

Programmation objet en Java

309

'

Programmation par contrat : Fraction (3/4)

/** Changer
//@ ensures
//@ ensures
public void

le signe de la fraction. */
getNumerateur() == - \old(getNumerateur());
getDenominateur() == \old(getDenominateur());
opposer()
{ num = - num; }

/** @return la fraction oppose */


//@ ensures \result.getNumerateur() == - getNumerateur();
//@ ensures \result.getDenominateur() == getDenominateur();
public Fraction opposee() {
return new Fraction(- getNumerateur(), getDenominateur());
}
/** Inverser la fraction. */
//@ requires getNumerateur() != 0;
//@ ensures getNumerateur() * \old(getDenominateur())
//@
== \old(getNumerateur()) * getDenominateur();
public void inverser()
{ set(den, num); }
/** Inverse de la fraction. */
//@ requires getNumerateur() != 0;
//@ ensures \result.produit(this).equals(UN);
public Fraction inverse()
{ return new Fraction(den, num); }

&
X. Crgut

Programmation objet en Java

310

'

Programmation par contrat : Fraction (4/4)

/** le produit avec une autre fraction. */


//@ ensures \result.equals(new Fraction(num * autre.num, den * autre.den));
public /*@ pure @*/ Fraction produit(Fraction autre) {
return new Fraction(num * autre.num, den * autre.den);
}
/** galit logique entre fractions. */
//@ ensures \result == ((getNumerateur() == autre.getNumerateur()
//@
&& getDenominateur() == autre.getDenominateur()));
public /*@ pure @*/ boolean equals(Fraction autre) {
return num == autre.num && den == autre.den;
}
/** Afficher la fraction. */
public void afficher()
{
System.out.print(getNumerateur());
if (getDenominateur() > 1) {
System.out.print("/" + getDenominateur());
}
}
}

&
X. Crgut

Programmation objet en Java

311

'

Programmation par contrat : utilisation de Fraction

public class TestFractionDBC {


public static void main (String args []) throws java.io.IOException {
int n, d;
// numrateur et dnominateur dune fraction
do {
n = Console.readInt("Numrateur : ");
d = Console.readInt("Dnominateur : ");
if (d == 0)
System.out.println("Le dnominateur doit tre > 0 !");
} while (d == 0);
Fraction f = new Fraction(n, d);
System.out.print("La fraction est : ");
f.afficher();
System.out.println();
if (f.getNumerateur() != 0) {
System.out.print("Son inverse est : ");
f.inverse().afficher();
System.out.println();
}
}
}

&

X. Crgut

Programmation objet en Java

312

'

Programmation par contrat et constructeurs


Un constructeur a pour rle dtablir linvariant de lobjet en cours de
cration.
Justification : Les invariants doivent toujours tre vrais, donc ds la
cration dun objet.
Remarque : Ce rle des constructeurs permet de justifier leur prsence et le
fait quun constructeur est toujours appliqu lors de la cration dun objet.
Cependant le rle du constructeur est, mon sens, plus important : il sert
non seulement tablir linvariant mais aussi initialiser lobjet dans ltat
souhait par lutilisateur.
&

X. Crgut

Programmation objet en Java

313

'

Programmation par contrat et hritage

Analogie avec la sous-traitance : Le fournisseur peut sous-traiter le travail


pour un tarif infrieur ou gal au prix ngoci avec le client en exigeant une
qualit au moins gale.
Sous-traitance = redfinition dune mthode dans une sous-classe.
Rgles respecter :
affaiblir les prconditions (require else en Eiffel) ;
renforcer les postconditions (ensure then en Eiffel) ;
les invariants sont hrits et peuvent tre renforcs.
Attention : Ni le langage, ni le compilateur ne peuvent vrifier ces rgles.
Cest donc au programmeur dtre vigilant !
Attention : Linstrumentation ne permet gnralement pas de vrifier cette
rgle.

&

X. Crgut

Programmation objet en Java

314

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

public class RacineCarree {


/** Racine carre. */
public static double RC(double x) {
assert x >= 0 : "x ngatif " + x;
double result = Math.sqrt(x);
assert result >= 0 : result;
assert result * result == x : result;
return result;
}
public static void main (String args []) {
double d = Console.readDouble("Donnez un rel : ");
if (d >= 0) {
// test explicite !!!
System.out.println("RC(" + d + ") = " + RC(d));
}
for (int i = 0; i < 10; i++) {
System.out.println("RC(" + i*i + ") = " + RC(i*i));
}
// Attention, sans test !!!
System.out.println("RC(" + (-d) + ") = " + RC(-d));
}

&

X. Crgut

Utilisation de la clause assert

Programmation objet en Java

315

'

Utilisation de la clause assert

La clause assert a t ajoute la version 1.4 du langage Java.


Elle modifie le langage et, en consquence, il faut dire explicitement au
compilateur dutiliser la version 1.4 du langage.
licorne> javac -source 1.4 RacineCarree.java

Par dfaut, les assertions ne sont pas vrifies. Elles sont actives avec
loption -ea et dsactives avec -da au niveau de la classe ou du paquetage
(-esa et -dsa pour les classes systme).
licorne> java -ea RacineCarree # toutes les classes sauf systme
Donnez un rel : 4
RC(4.0) = 2.0
RC(0) = 0.0
...
RC(81) = 9.0
Exception in thread "main" java.lang.AssertionError: x ngatif -4.0
at RacineCarree.RC(RC_assert.java:4)
at RacineCarree.main(RC_assert.java:20)

&
X. Crgut

Programmation objet en Java

316

'

Exceptions vs programmation par contrat

Remarque : Ce sont deux techniques non exclusives !


Cas o prfrer les exceptions :
lvaluation de la prcondition est coteuse et redondante avec le traitement
(exemples : parseInt, recherche dans un arbre, etc.) ;
impossibilit de donner une prcondition (exemple : appel de procdure
distance, criture dans un fichier, etc.) ;
cas anormal mais que lon considre comme pouvant se produire (6= erreur de
programmation) : saisies utilisateur, etc.
Cas o prfrer la programmation par contrat :
les parties lies par contrats sont matrises ;
Remarque : La JVM charge dynamiquement les classes
= SUN prfre les exceptions pour les mthodes publiques !
erreur manifeste de programmation (non rcuprable) ;
efficacit du programme (viter des tests dans les mthodes appeles) ;
mcanisme support par lenvironnement de dveloppement !

&

X. Crgut

Programmation objet en Java

317

'

Classes internes...

&
X. Crgut

Programmation objet en Java

318

'

Exercice 43 : Amliorer OutilsListe.somme


Dans lexercice 18, nous avons dfini une interface Liste et deux
ralisations ListeTab (les lments sont stocks dans un tableau) et
ListeChane (les lments sont chans). Nous avons galement crit une
classe OutilsListe qui dfinit la mthode somme.

/** Quelques mthodes utiles sur les listes. */


public class OutilsListe {
/* Calculer la somme des rels dune liste.
* @param l la liste dont on veut sommer les valeurs
* @return la somme des valeurs de l */
static public double somme(Liste l) {
double resultat = 0;
for (int i = 0; i < l.taille(); i++) {
resultat += l.item(i);
}
return resultat;
}
}

Sommer les lments dune liste chane est inefficace. Proposer un


mcanisme plus efficace... et gnral.
&
X. Crgut

Programmation objet en Java

319

'

Solution

Problme : Utiliser le mthode item(int) nest pas efficace sur ListeChane


(parcours des cellules depuis la premire).
But : Fournir le moyen de faire un parcours de la liste (donc gnral) qui
puisse tre efficace pour ListeTab, ListeChane...
Solution : Dfinir une interface qui abstrait le parcours dune liste.
1
2
3
4
5
6
7
8
9
10

/** Un iterateur permet de parcourir tous les lments dune liste.


1.1 */
* @version
public interface Iterateur<T> {
/** Est-ce quil y a encore des lments parcourir ? */
boolean encore();
/** Rcuprer llment suivant. */
T suivant();
}

et dfinir une ralisation pour ListeTab, ListeChane...


&

X. Crgut

Programmation objet en Java

320

'
1
2
3
4
5

Ajouter un itrateur sur Liste

public interface Liste {


/** Litrateur qui permet de raliser un parcours de la liste. */
Iterateur iterateur();
}

Nouvelle criture de somme :


1
2
3
4
5
6
7
8
9
10
11
12
13
14

/** Quelques mthodes utiles sur les listes. */


public class OutilsListe {
/* Calculer la somme des rels dune liste.
* @param l la liste dont on veut sommer les valeurs
* @return la somme des valeurs de l */
static public double somme(Liste l) {
double resultat = 0;
Iterateur it = l.iterateur();
while (it.encore()) {
resultat += it.suivant();
}
return resultat;
}
}

&

X. Crgut

Programmation objet en Java

321

'

Diagramme de classes des itrateurs de Liste


<<utilise>>
<< interface >>
Itrateur

OutilsListe
interface

somme(liste: Liste): double

Liste
suivant(): T
encore(): boolean

ItrateurTab
ListeTab
suivant(): T
encore(): boolean

suivante 0..1

ItrateurChain

Cellule
ListeChane

0..1

suivant(): T
encore(): boolean

&
X. Crgut

premire

Programmation objet en Java

lment: double 0..1

322

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

/** Itrateur sur un tableau (par exemple de ListeTab)


Xavier Crgut
* @author
1.1 */
* @version
class IterateurTab implements Iterateur {
private double[] elements; // les lments parcourir
private int nb;
// le nb dlements
private int curseur;
// lment parcourir
public IterateurTab(double[] elts, int taille) {
this.elements = elts;
this.nb = taille;
this.curseur = 0;
}
public boolean encore() {
return this.curseur < this.nb;
}
public double suivant() {
return this.elements[this.curseur++];
}

&
X. Crgut

Programmation objet en Java

323

'

Discussion

De manire gnrale, litrateur (ici IterateurTab) devrait avoir accs la structure


de donnes (ici ListeTab). Voir le diagramme de classe !
Justification : dtecter les modifications concurrentes en consultant une information
de la structure de donnes (nombre de modifications).
IterateurTab est une classe extrieure ListeTab
IterateurTab doit accder la reprsentation interne de ListeTab
= deux solutions :
1.

ajoute des mthodes de manipulation de sa reprsentation interne


MAIS violation du principe dencapsulation !

2.

ListeTab

ListeTab

fournit en paramtre du constructeur de IterateurTab ses donnes


internes (solution choisie).

Comment faire pour garder une solution plus proche du diagramme de classe :
litrateur a accs la structure de donnes ?
= On utilise une classe interne !

&

X. Crgut

Programmation objet en Java

324

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

public class ListeTab<T> implements Liste<T> {


private T[] elements;
// les lments de la liste
private int nb;
// la taille de la liste
public Iterateur<T> iterateur() {
return new IterateurTab<T>(this);
}
static private class IterateurTab<T> implements Iterateur<T> {
private ListeTab<T> liste; // liste parcourir
private int curseur;
// lment parcourir
public IterateurTab(ListeTab<T> l) {
this.liste = l;
this.curseur = 0;
}
public boolean encore() {
return this.curseur < this.liste.nb;
}
public T suivant() {
return this.liste.elements[this.curseur++];
}

&
X. Crgut

Programmation objet en Java

325

'

Discussion sur la classe interne statique


Ici, nous avons dfini une classe interne statique et prive.
Remarque : Une classe interne a un droit daccs.
Intrt de la classe interne statique : elle peut accder toutes les
caractristiques (y compris private) de la classe qui la contient.
Ici, ceci permet donc :
de conserver lencapsulation de ListeTab : aucune mthode ajoute ;
de conserver le sens du diagramme UML : IterateurTab utilise ListeTab ;
MAIS ceci est assez lourd. Ne pourrait-on pas directement avoir accs
aux caractristiques de lobjet de la classe englobante ?
= Cest la notion de classe interne propre (non statique ) :
&

X. Crgut

Programmation objet en Java

326

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

public class ListeTab<T> implements Liste<T> {


private T[] elements;
// les lments de la liste
private int nb;
// la taille de la liste
public Iterateur<T> iterateur() {
return new IterateurTab();
}
private class IterateurTab implements Iterateur<T> {
private int curseur;
// lment parcourir
public IterateurTab() {
this.curseur = 0;
}
public boolean encore() {
return this.curseur < ListeTab.this.nb;
// accs lattribut nb de lobjet englobant
}
public T suivant() {
return elements[this.curseur++];
// implicitement ListeTab.this.elemnets
}

&
X. Crgut

Programmation objet en Java

327

'

Classe interne

Dfinition : Une classe interne est une classe dfinie lintrieur dune
autre classe.
Avantages : La classe interne est dans lespace de nom de lautre classe et a
donc accs toutes ses informations (y compris celles dclares private).
Classe interne membre : (T. 327) Elle contient un accs sur lobjet qui a
permis sa cration (et rcupre les paramtres de gnricit).
Liste<Double> ll = ...;
Iterateur<Double> it = ll.iterateur();
// it est construit partir de ll
ListeTab<Double> lt = ...;
Iterateur<Double> it2 = lt.new IterateurTab();

Classe interne statique : (T. 325) Elle nest associe aucun objet de la
classe englobante.

&
X. Crgut

Programmation objet en Java

328

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Classe anonyme

public class ListeTab<T> implements Liste<T> {


private T[] elements;
// les lments de la liste
private int nb;
// la taille de la liste
public Iterateur<T> iterateur() {
return new Iterateur<T>() {
private int curseur = 0;

// lment parcourir

public boolean encore() {


return this.curseur < nb;
}

};

public T suivant() {
return elements[this.curseur++];
}
// Ne pas oublier le point-virgule

}
}

Une classe anonyme est une classe qui na quune seule instance.
Peut avoir accs aux variables locales du sous-programme condition
quelles soient dclares final ;
&

X. Crgut

Programmation objet en Java

329

'

Principales API du langage Java

&
X. Crgut

Programmation objet en Java

330

'

Les collections

Dfinition : Une collection est un objet qui reprsente un groupe


dlments de type E (gnricit depuis java 1.5).
Principaux constituants :
Interfaces : types abstraits de donnes qui reprsentent les collections :
un type (liste, ensemble, file, tableau associatif, etc.)
les oprations disponibles sur ce type
la smantique (informelle) des oprations
Ralisations (implantations) : ralisations concrtes des interfaces en
sappuyant sur diffrentes solutions pour stocker les lments (tableau,
structures chanes, table de hachage, arbre, etc.).
Algorithmes :
algorithmes classiques sur une collection (chercher, trier, etc.)
polymorphes : fonctionnent avec plusieurs collections
&

X. Crgut

Programmation objet en Java

331

'

Intrt des collections

Rduire les efforts de programmation


rutiliser les collections de lAPI
Augmenter la vitesse et la qualit des programmes
efficaces car ralises par des experts
les collections fournissent des oprations de haut niveau (testes !)
possibilit de substituer une ralisation par une autre
Permettre linteroprabilit entre diffrentes API
les donnes changes le sont sous forme de collections.
Faciliter lapprentissage de nouvelles API
pas de partie spcifique traitant les collections
Favoriser la rutilisation logicielle :
les anciens algorithmes fonctionneront avec les nouvelles collections
et les anciennes collections avec les nouveaux algorithmes

&

X. Crgut

Programmation objet en Java

332

'

Hirarchie des structures de donnes en Java

Voici un extrait du diagramme de classes concernant les structures de


donnes de Java.
Iterable
values

Map

entrySet

Iterator

Collection

List

Set

Queue

1.5

Deque

1.6

keySet

SortedSet

SortedMap

HashMap TreeMap

HashSet

TreeSet

ArrayList

Vector

LinkedList

ArrayDeque

Remarque : Vector est une ancienne classe qui a t modifie pour faire
partie de la hirarchie Collection. Cest la seule classe synchronise .
&
X. Crgut

Programmation objet en Java

333

'

Principales collections

Collection : le type le plus gnral des collections.


List : les lments ont une position (numro dordre)
Set : Notion densemble au sens mathmatique :
pas de double possible
SortedSet : un ensemble muni dune relation dordre (lments tris)
ne pas faire de modification sur un objet qui a une incidence sur la
relation dordre utilise !
Queue : une file, avec politique FIFO ou autre.
Deque : (Double Ended Queue) : sous-type de Queue qui permet toutes
les manipulations sur le dbut et la fin de la file.
Map : tableau associatif, i.e. manipulation dune information partir
dune cl (p.ex. rpertoire tlphonique).
Attention, ce nest pas un sous-type de collection !
SortedMap : un tableau associatif avec une relation dordre sur les cls.
&

X. Crgut

Programmation objet en Java

334

'

Linterface java.util.Collection

Linterface Collection est la racine de larbre dhritage des structures de


donnes de Java.
Proprits : Voici quelques proprits des collections :
Avant Java 1.5, les lments dune collection tait Object (T. 241).
Une collection peut autoriser ou non plusieurs occurrences dun mme
lment (List vs Set).
Les lments peuvent tre ordonns ou non (List vs Set).
Les lments peuvent tre tris ou non (Set vs SortedSet).
Toute ralisation dune Collection devrait dfinir :
un constructeur par dfaut (qui cre une collection vide) et
un constructeur qui prend en paramtre une collection (conversion).
Certaines mthodes peuvent ne pas avoir de sens pour un sous-type qui
doivent alors lever UnsupportedOperationException.
Des mthodes peuvent lever ClassCastException (choix ralisation).
&
X. Crgut

Programmation objet en Java

335

'

Linterface java.util.Collection<E>

Cest la racine de la hirachie dfinissant les collections (groupe


dlments).
boolean add(E o)
// ajouter llment (false si doubles interdits)
boolean addAll(Collection<? extends E> c) // ajouter les lments de c
void clear()
// supprimer tous les lments de la collection
boolean contains(Object o)
// est-ce que la collection contient o ?
boolean containsAll(Collection<?> c)
// ... tous les lments de c ?
boolean isEmpty()
// aucun lment ?
Iterator<E> iterator()
// un itrateur sur la collection
boolean remove(Object o) // supprimer lobjet o (collection change ?)
boolean removeAll(Collection<?> c)
// supprimer tous les lts de c
boolean retainAll(Collection<?> c)
// conserver les lments de c
int size()
// le nombre dlments dans la collection
Object[] toArray() // un tableau contenant les lments de la collection
<T> T[] toArray(T[] a) // un tab. (a si assez grand) avec les lments

Remarque : Certaines oprations sont optionnelles ou imposent des


restrictions. Dans ce cas, elles doivent lever une exception !

&
X. Crgut

Programmation objet en Java

336

'

Linterface java.util.List<E>
Structure de donnes o chaque lment peut tre identifi par sa position.
boolean add(E e)
// ajouter e la fin de la liste
void add(int i, E e)
// ajouter e lindex i
E set(int i, E o)
boolean addAll(int, Collection<? extend E> c)
// ... insrs partir de i
E get(int i)
// lment lindex i
int indexOf(Object o)
// index de lobjet o dans la liste ou -1
int lastIndexOf(Object o)
// dernier index de o dans la liste
List<E> subList(int from, int to)
// liste des lments [from..to[
E remove(int i)

// supprimer llment lindex i

ListIterator<E> listIterator()
ListIterator<E> listIterator(int i)

// itrateur double sens


// ... initialis lindex i

... et celles de collection !

&
X. Crgut

Programmation objet en Java

337

'

La classe java.util.Vector<E>

Objectif : Disposer de tableaux automatiquement redimensionnables.


Remarque : La classe Vector est dfinie dans le paquetage java.util.
Constructeurs : Sauf contre-indication, ils crent des vecteurs vides.
Vector(int capacitInitiale, int incrmentCapactit)
Vector(int capacitInitiale)
// Vector(capacitInitiale, 4)
Vector()
// Vector(10);
Vector(Collection<? extends E> c) // vecteur contenant les lments de c

Mthodes lmentaires : (quivalentes celles des tableaux)


int size()
int capacity()

// le nombre dlments du vecteur (taille effective)


// capacit du vecteur

E get(int index)
E elementAt(int index)

// vecteur[index]
// get(index)

0 <= index < size()

boolean add(E o)

// ajouter o comme dernier lment du vecteur avec


// redimensionnement si ncessaire (renvoie true)
boolean addElement(E o) // idem add(Object)
add(int index, E o)
// vecteur[index] = o et 0 <= index <= size()
set(int index, E o)
// vecteur[index] = o et 0 <= index < size()

&
X. Crgut

Programmation objet en Java

338

'

La classe java.util.Vector (suite)

E firstElement()
E lastElement()

// get(0)
// get(size()-1)

boolean isEmpty()

// aucun lment ?

void clear()
// supprimer tous les lments du vecteur
void removeAllElements()
// idem clear()
boolean remove(Object o)
// supprime la premire occurence
E remove(int index)
// supprimer vecteur[index] (chang ?)
boolean contains(Object o)
int
int
int
int

// vecteur contient-il o ?

indexOf(Object o)
// premier index de o dans le vecteur
indexOf(Object o, int i)
// ... partir de lindice i
lastIndexOf(Object o)
// dernier index de o dans le vecteur
lastIndexOf(Object o, int i)
// ... partir de lindice i

void setSize(int ns)

// changer la taille effective du vecteur

Object[] toArray()

// un tableau contenant les lments du vecteur

Remarque : Il existe des mthodes qui manipulent une collection.


&
X. Crgut

Programmation objet en Java

339

'

Queue

ajoute par Java 1.5


implante les oprations spcifies sur Collection
fournit des oprations supplmentaires pour :
lve une exception

retourne une

valeur spcifique

ajouter

add(E)

offer(E)

false

supprimer

remove

poll

null

examiner

element

peek

null

llment null est gnralement interdit dans une Queue.


principalement une politique type FIFO (First In, First Out) mais dautres
politiques sont possibles (file avec priorit).

&
X. Crgut

Programmation objet en Java

340

'

Map : tableau associatif

Type gnrique : Map<K, V>


K : type des cls
V : type des valeurs
V put(K k, V v)
V get(Object k)
V remove(Object k)

// ajouter v avec la cl k (ou remplacer)


// la valeur associe la cl ou null
// supprimer lentre associe k

boolean containsKey(Object k)
// k est-elle une cl utilise ?
boolean containsValue(Object v) // v est-elle une valeur de la table ?
Set<Map.Entry<K, V>> entySet()
Set<K>
keySet()
Collection<V>
values()

// toutes les entres de la table


// lensemble des cls
// la collection des valeurs

void putAll(Map<? extends K,? extends V> m)


int size()
boolean isEmpty()
void clear()

&
X. Crgut

// ajouter les entres de m

// nombre dentres dans la table


// la table est-elle vide ?
// vider la table

Programmation objet en Java

341

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

import java.util.Map;
import java.util.HashMap;
public class CompteNbOccurrences {
/** Compter le nombre doccurrences des chanes de args... */
public static void main(String[] args) {
Map<String, Integer> occ = new HashMap<String, Integer>();
for (String s : args) {
if (occ.containsKey(s)) {
occ.put(s, 1 + occ.get(s));
} else {
occ.put(s, 1);
}
}
System.out.println("occ = " + occ);
System.out.println("cls = " + occ.keySet());
System.out.println("valeurs = " + occ.values());
System.out.println("entres = " + occ.entrySet());
// afficher chaque entre
for (Map.Entry<String, Integer> e : occ.entrySet()) {
System.out.println(e.getKey() + " --> " + e.getValue());
}

&
X. Crgut

Exemple dutilisation des Map

Programmation objet en Java

342

'

Exemple dutilisation des Map (exemple)


Le rsultat de java

CompteNbOccurrences A B C A C D E A A D E

est :

occ = {D=2, E=2, A=4, B=1, C=2}


cls = [D, E, A, B, C]
valeurs = [2, 2, 4, 1, 2]
entres = [D=2, E=2, A=4, B=1, C=2]
D --> 2
E --> 2
A --> 4
B --> 1
C --> 2

Question : Comment afficher les chanes dans lordre ?

&
X. Crgut

Programmation objet en Java

343

'

Les algorithmes : la classe Collections

Classe utilitaire qui contient des mthodes pour :


trier les lments dune collection
rapide (en n log(n))
stable (lordre est conserv entre les lments gaux)
mlanger les lments dune collection
manipulation des donnes :
reverse : inverser lordre des lments dune List
fill : remplacer tous les lments dune List par une valeur
copy : les lments dune liste source vers une liste destination
swap : permuter les lments de deux listes
addAll : ajouter des lments une collection
Chercher des lments (binarySearch), ncessite une relation dordre
Compter le nombre doccurrences dun lment (frequency) et vrifier si deux
collections sont disjointes (disjoint)
Trouver le min et le max (ncessite une relation dordre).
Remarque : Voir linterface Comparator pour les relations dordre.

&
X. Crgut

Programmation objet en Java

344

'

Linterface java.util.Iterator<E>
Objectif : Un itrateur est un objet qui permet de parcourir tous les
lments dune collection.
boolean hasNext() // reste-t-il des lments dans la collection ?
E next()
// llment suivant (et avancer)
void remove()
// supprimer llment (peut ne pas tre dfinie)

Exemple dutilisation :
Collection<Double> c = ...
Iterator<Double> it = c.iterator();
while (it.hasNext()) {
Double lment = it.next(); // retourne llment courant et avance
// manipuler lment...
}

Inspiration : Analogie avec le parcours dun tableau.


&

X. Crgut

Programmation objet en Java

345

'

Linterface java.util.Iterable<E>

public interface Iterable<E> {


Iterator<E> iterator();
}

Intrt : Il est possible dutiliser foreach sur toute classe qui ralise
Iterable.
Iterable<E> collection = ...
for (E o : collection) {
faire(o);
}

Ceci est quivalent :


Iterable<E> collection = ...
Iterator<E> it = collection.iterator();
while (it.hasNext()) {
E o = it.next();
faire(o);
}

&

X. Crgut

Programmation objet en Java

346

'

Les entres/sorties Motivation

Entres/sorties : communication dun programme avec son environnement


Exemples dentres :
clavier, souris, joystick
scanner, camra, etc.
lecture dun fichier sur disque
rception dune page web depuis un serveur distant
...
Exemples de sorties :
affichage sur un cran
criture dun fichier sur un disque local
envoi dune requte un serveur
envoi dune commande un robot
impression dun document vers un fax, une imprimante, etc.
&

X. Crgut

Programmation objet en Java

347

'

Autres difficults
Diversit des systmes dexploitation
Fichiers de natures diffrentes :
texte : code source, script, configuration, courrier...
binaire : excutables, fichiers compresss, etc.
spciaux : /dev/ (priphriques)
rpertoires : contient des rfrences dautres fichiers
liens symboliques : autre accs un mme fichier
Diffrents codages (fichier texte) :
latin1, utf8, ASCII, etc.
un caractre cod sur 1 octet, 2 octets, 4 octets, voir un nombre variable
recode : 281 codages pris en charge
&

X. Crgut

Programmation objet en Java

348

'

Solution : Abstraction des E/S


Constatations :
Toute E/S peut tre reprsente par une suite de bits
Ceux-ci sont regroups en octets (bytes)
Abstraction des entres/sorties : flux (stream) :
accs squentiel aux donnes
flux dentre : InputStream
flux de sortie : OutputStream
Abstraction des oprations possibles
oprations dentre (lecture : read)
oprations de sortie (criture : write)
Concrtisation des flux : Fichiers, Tableau, Pipe, etc.
&

X. Crgut

Programmation objet en Java

349

'

Les entres/sorties en Java

LAPI dentre/sortie est dfinie dans le paquetage java.io. Elle :


fournit une interface standard pour grer les flux dentre/sortie ;
libre le programmeur des dtails dimplantation lis une plateforme
particulire.
Flux : Squence ordonne de donnes qui a une source (input stream) ou
une destination (output stream).
Classes de base : Java propose 4 classes principales (abstraites) pour les
entres/sorties qui seront ensuite spcialises en fonction de la nature de la
source ou de la destination.
Caractres
Octets

&
X. Crgut

Entre

Reader

InputStream

Sortie

Writer

OutputStream

Programmation objet en Java

350

'

La classe InputStream

But : Lire des octets (bytes) depuis un flux dentre.


public abstract class InputStream {
public abstract int read() throws IOException;
// Lire un octet renvoy sous la forme dun entier entre 0 et 255.
// Retourne -1 si le flux dentre est termin. Bloquante.
public int read(byte[] buf, int off, int len) throws IOException;
// Lire au plus len octets et les stocker dans buf partir de off.
// Retourne le nombre doctets effectivement lus (-1 si fin de flux).
// @throws IndexOutOfBoundsException, NullPointerException...
public int read(byte[] b) throws IOException;
// Idem read(b, 0, b.length)
public long skip(long n) throws IOException
// Sauter (et supprimer) n octets du flux.
// Retourne le nombre doctets effectivement sauts.
public void close() throws IOException;
// Fermer le flux et librer les ressources systme associes.
public int available() throws IOException;
// nombre doctets disponibles (sans bloquer)
}

&
X. Crgut

Programmation objet en Java

351

'

La classe OutputStream

But : crire des octets (bytes) dans un flux de sortie.


public abstract class OutputStream {
public abstract void write(int b) throws IOException;
// crire b dans ce flux (seuls les 8 bits de poids faible).
public void write(byte[] buf, int off, int len) throws IOException;
// crire len octets de buf[off] buf[off+len-1] dans ce flux.
// @throws IndexOutOfBoundsException, NullPointerException...
public void write(byte[] b) throws IOException;
// Idem write(b, 0, b.length)
public void flush() throws IOException
// Vider ce flux.
// Si des octets ont t buffriss, ils sont effectivement crits.
public void close() throws IOException;
// Fermer le flux et librer les ressources systme associes.
}

&
X. Crgut

Programmation objet en Java

352

'

Les classes Reader et Writer

Principe : quivalentes InputStream et OutputStream mais avec des


caractres et non des octets.
Remarque : int pour stocker 16 bits dun caractres ou -1 pour fin du flux.
public abstract class Reader {
public int read() throws IOException;
public abstract int read(char[] buf, int off, int len) throws IOException;
public int read(char[] b) throws IOException;
public long skip(long n) throws IOException
public abstract void close() throws IOException;
public boolean ready() throws IOException;
// prt tre lu ?
}
public abstract class Writer {
public void write(int b) throws IOException;
public abstract void write(char[] buf, int off, int len) throws IOException;
public void write(char[] b) throws IOException;
public void write(String str) throws IOException;
public void write(String str, int off, int len) throws IOException;
public void flush() throws IOException
public abstract void close() throws IOException;
}

&
X. Crgut

Programmation objet en Java

353

'

Concrtisations de InputStream
InputStream

SequenceInputStream

ByteArrayInputStream

FileInputStream

ObjectInputStream

PipedInputStream

StringBufferInputStream

Principe : une sous-classe de InputStream...


doit dfinir la mthode read(byte) ;
devrait redfinir read(byte[], int, int) pour en donner une version plus
efficace
&
X. Crgut

Programmation objet en Java

354

'

Concrtisations de OutputStream
OutputStream

ByteArrayOutputStream

FileOutputStream

ObjectOutputStream

PipedOutputStream

Principe : Une sous-classe de OutputStream...


doit dfinir la mthode write(byte) ;
devrait redfinir write(byte[], int, int) pour en donner une version plus
efficace
&
X. Crgut

Programmation objet en Java

355

'

Concrtisations de ces classes abstraites


File* : Flux sur des fichiers
Constructeur avec le nom du fichier, File ou FileDescriptor
Peut lever les exceptions :
FileNotFoundException
SecurityException

ByteArray* : Flux dans un tableau doctets


Object* : Flux dobjets (srialisation)
Piped* : Flux sur des tubes (connexion entre threads)
Mais aussi :
StringBufferInputStream : Flux vers des chanes de caractres
SequenceInputStream : Lecture depuis plusieurs flux successivement

&

X. Crgut

// le fichier nexiste pas


// pas de droit en lecture/criture

Programmation objet en Java

356

'

Exemple : Copier un fichier (version 1)


public static void copier(String destination, String source)
throws IOException
{
FileInputStream in = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(destination);
int c = in.read();
while (c != -1) {
out.write(c);
c = in.read();
}
in.close();
out.close();
}

&

X. Crgut

Programmation objet en Java

357

'

Exemple : Copier un fichier (version 2)


public static void copier2(String destination, String source)
throws IOException
{
FileInputStream in = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(destination);
byte tampon[] = new byte[256];
int nb; // nombre doctets lus
while ((nb = in.read(tampon)) > 0) {
out.write(tampon, 0, nb);
}
in.close();
out.close();
}

&

X. Crgut

Programmation objet en Java

358

'

La classe java.io.File

But : Reprsentation abstraite des chemins daccs aux fichiers/rpertoires


Attention : Ne permet ni de lire, ni dcrire le contenu dun fichier !
public class File implements Comparable<File> {
File(String nomChemin)
File(File parent, String fils)
File(String cheminParent, String fils)
File(URI uri)
// droits daccs (1.6)
boolean canExecute()
boolean canRead()
boolean canWrite()
boolean setWritable(boolean writable, boolean ownerOnly)
boolean setWritable(boolean writable) // setWritable(writable, true)
... idem pour setExecutable, setReadable
// le nom du chemin
String getName()
// quivalent de basename
String getParent()
// quivalent de dirname
String getPath()
// ...
String getAbsolutePath()
// le chemin absolu correspondant

&

X. Crgut

Programmation objet en Java

359

'

String getCanonicalPath()
// absolu et unique
File getAbsoluteFile()
// ce fichier avec un chemin absolu
File getCanonicalFile()
// ce fichier avec un chemin canonique
URI getURI()
// URI dsignant ce fichier
boolean isAbsolute() // est un chemin absolu
// nature et caractristiques
boolean isDirectory() // rpertoire ?
boolean isFile()
// fichier ?
boolean isHidden()
// cach ?
long length()
// longueur en octet
long lastModified()
// date de dernire modification
boolean setLastModified(long)

// accs au contenu dun rpertoire


String[] list() // noms des lments contenus ds ce rpertoire (ou null)
String[] list(FilenameFilter)
// avec filtre
File[] listFiles()
// lments contenus dans ce rpertoire (ou null)
File[] listFiles(FilenameFilter)
// avec filtre
static File[] listRoots()
// liste les racines
// espace disponible
long getTotalSpace() // taille de la partition
long getFreeSpace()
// nombre doctets non allous sur cette partition
long getUsableSpace() // octets disponibles sur partition pour JVM (1.6)

&

X. Crgut

Programmation objet en Java

360

'

// liens avec le systme de gestion de fichier


boolean exists()
// est-ce que le fichier existe ?
boolean createNewFile() // cre un fichier avec ce nom ssi nexiste pas
boolean delete()
// dtruit le fichier correspondant
boolean deleteOnExit() // fichier doit tre dtruit quand la JVM finit
boolean mkdir()
// crer le rpertoire correspondant ce fichier
boolean mkdirs()
// ... y compris les rpertoires parents inexistants
boolean renameTo(File dest)
// dpendant de la plate-forme
// cration de nom de fichiers temporaires
static File createTempFile(String prefix, String suffix, File directory)
static File createTempFile(String prefix, String suffix)
}

&
X. Crgut

Programmation objet en Java

361

'

Exemple dutilisation de File

But : afficher les fichiers et le contenu des rpertoires rcursivement


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import java.io.File;
public class Lister {
public static void lister(File file) {
System.out.print(file.getName());
if (!file.exists()) {
System.out.println(": fichier ou rpertoire inexistant !");
} else if (file.isDirectory()) {
System.out.println(":");
lister(file, file.list());
System.out.println();
}
else {
if (file.canExecute()) {
System.out.print("*");
}
System.out.println();
}
}

&

X. Crgut

Programmation objet en Java

362

'

20
21
22
23
24
25
26
27
28
29
30

public static void lister(File parent, String[] noms) {


for (String nom: noms) {
lister(new File(parent, nom));
}
}
public static void main(String[] args) {
lister(null, args);
}
}

&
X. Crgut

Programmation objet en Java

363

'

Filtres : FilterInputStream et FilterOutputStream

Principe : Ajouter de nouvelles fonctionnalits des flux existants


# in

InputStream

...

ByteArrayInputStream

FilterInputStream

FileInputStream
BufferedInputStream

...
InflaterInputStream

DataInputStream

PushbackInputStream

public class FilterInputStream {


protected InputStream in;
// le flux filtr (dcor)
protected FilterInputStream(InputStream in)
// filtrer un flux existant
// protg ==> ne peut tre appel que depuis une sous-classe
... toutes les mthodes m de InputStream sont rediriges sur in.m

&

Remarque : Mme principe pour FilterOutputStream

X. Crgut

Programmation objet en Java

364

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import java.io.*;
public class FlipCaseInputStream extends FilterInputStream {
public FlipCaseInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int c = super.read();
// idem in.read()
int newC = c;
if (Character.isUpperCase(c)) {
newC = Character.toLowerCase(c);
} else if (Character.isLowerCase(c)) {
newC = Character.toUpperCase(c);
}
return newC;
}
}

&

X. Crgut

Dfinir un FilterInputStream

Programmation objet en Java

365

'

Dfinir un FilterInputStream : Utilisation


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import java.io.*;
public class TestFlipCaseInputStream {
public static void afficher(InputStream in) throws IOException {
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
}
public static void main(String[] args) throws IOException {
InputStream inStream = new FlipCaseInputStream(
new FileInputStream(args[0]));
afficher(inStream);
inStream.close();
}
}

&

X. Crgut

Programmation objet en Java

366

'

Principaux filtres
Buffered* : Ajouter la bufferisation sur un flux existant
Les informations ne sont pas directement crites dans le flux
En entre : ajoute les fonctionalits mark(int) et reset
sur BufferedReader, ajoute readLine()
En sortie : opration flush() pour forcer lcriture dans le flux
PrintStream et PrintWriter : Surcharge print (et println) pour les
types primitifs et Object.
Data* : crit les types primitifs Java de manire portable.
Compression de flux :
Entre : Inflater avec comme spcialisations GZIP, Zip, Jar
Sortie : Deflater avec comme spcialisations GZIP, Zip, Jar
Pushback* : Remettre (unread) des lments dans le flux dentre.
&
X. Crgut

Programmation objet en Java

367

'

Exemple de combinaison de filtres


1
2
3
4
5
6
7
8
9
10
11
12
13

import java.io.*;
public class TestFiltres {
public static void main(String[] args) throws IOException {
DataOutputStream dos =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("/tmp/fichier.out")));
dos.writeDouble(12.5);
dos.writeUTF("Dupond");
dos.writeInt(421);
dos.close();
}
}

&
X. Crgut

Programmation objet en Java

368

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

import java.io.*;
import java.util.zip.GZIPOutputStream;
public class GZipper {
public static void zipper(String nom) throws IOException {
String nomSortie = nom + ".gz";
GZIPOutputStream sortie = new GZIPOutputStream(
new FileOutputStream(nomSortie));
InputStream entree = new FileInputStream(nom);
int c;
while ((c = entree.read()) != -1) {
sortie.write(c);
}
entree.close();
sortie.close();
}

&
X. Crgut

Exemple : Compresser un fichier (GZIP)

public static void main(String[] args) throws IOException {


for (String nomFichier : args) {
zipper(nomFichier);
}
}

Programmation objet en Java

369

'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

import java.io.*;
import java.util.zip.*;
public class Zipper {
public static void zipper(String nomArchive, String[] noms)
throws IOException {
ZipOutputStream sortie = new ZipOutputStream(
new FileOutputStream(nomArchive));
for (String nom: noms) {
// ajouter une entre
sortie.putNextEntry(new ZipEntry(nom));
InputStream entree = new FileInputStream(nom);
int c;
while ((c = entree.read()) != -1) {
sortie.write(c);
}
entree.close();
sortie.closeEntry();
}
sortie.close();
}

&

X. Crgut

Exemple : Compresser une archive Zip

public static void main(String[] args) throws IOException {


zipper("/tmp/tout.zip", args);
}

Programmation objet en Java

370

'

Exemple : Dcompresser un fichier Zip


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import java.io.*;
import java.util.zip.*;
public class Dezipper {
public static void main(String[] args) throws IOException {
ZipInputStream zin = new ZipInputStream(
new FileInputStream(args[0]));
ZipEntry entree = zin.getNextEntry();
while (entree != null) {
String nomEntree = "/tmp/" + entree.getName();
FileOutputStream out = new FileOutputStream(nomEntree);
Copier.copier(out, zin);
out.close();
zin.closeEntry();
entree = zin.getNextEntry();
}
zin.close();
}
}

&
X. Crgut

Programmation objet en Java

371

'

Les classes InputStreamReader et OutputStreamWriter

But : Ces deux classes permettent de faire le lien entre


InputStream/OutputStream et Reader/Writer.
Elles sont des spcialisations Reader/Writer.
public class InputStreamReader extends java.io.Reader {
public InputStreamReader(InputStream in, String charSetName)
throws UnsupportedEncodingException
// Le flux dentre est in. charSetName est le nom du codage
// utilis (US-ASCII, ISO-8859-1, UTF-8...)
public InputStreamReader(InputStream in);
// Le flux est in avec le jeu de caractres par dfaut
}

Signature similaire pour OutputStream.


Exemple :
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));

&
X. Crgut

Programmation objet en Java

372

'

Complments

&
X. Crgut

Programmation objet en Java

373

'

La classe Object

En Java, si une classe na pas de classe parente, elle hrite implicitement de


la classe Object. Cest lanctre commun toutes les classes.
Elle contient en particulier les mthodes :
public boolean equals(Object obj); galit de this et obj (par dfaut
galit des adresses). Elle a cependant le sens dgalit logique et doit
donc tre redfinie (String, etc.)
public String toString(); chane de caractres dcrivant lobjet. Elle est
utilise dans print, println et loprateur de concatnation + par
lintermdiaire de String.valueOf(Object).
protected void finalize(); Mthode appele lorsque le ramasse-miettes
rcupre la mmoire dun objet.
protected Object clone(); Copie logique de lobjet (cf Cloneable)
public Class getClass(); Pour lintrospection.
...
&

X. Crgut

Programmation objet en Java

374

'

Linterface Cloneable

Problme : Comment faire pour obtenir une copie physique dun objet ?
Constatations :
Il est logique que ce soit la classe qui donne accs la copie.
La classe Object dfinit la mthode Object clone() mais en protected et
qui ne fait quune copie binaire des attributs (= partage des objets).
Consquence : Le concepteur dune classe doit dcider si ses objets
peuvent ou non tre clons. Dans laffirmative, il doit :
1. Implmenter linterface Cloneable ;
2. Redfinir la mthode clone en la dclarant public et en donnant un code
qui ralise effectivement la copie.
Remarque : Cloneable est une interface de marquage (le concepteur
montre quil a dfini correctement clone()) 6= interface classique.
&

interface Cloneable { } // Cloneable ne dclare rien !!!

X. Crgut

Programmation objet en Java

375

'

Linterface Cloneable : la classe Point

public class Point implements Cloneable {


private double x, y;
// coordonnes cartsiennes
...
public Object clone() {
try {
return super.clone();
// une copie superficielle suffit !
} catch (CloneNotSupportedException e) {
return null; // ne peut pas se produire car implements Cloneable
}
}
}

Remarque : Implmenter Cloneable autorise faire super.clone() !


Attention : Lors dun appel clone(), aucun constructeur nest appel !
Remarque : try/catch correspond la notion dexception (cf Exceptions).
Ici, lexception traduit la tentative de cloner un objet qui nimplante pas
linterface Cloneable.

&
X. Crgut

Programmation objet en Java

376

'

Linterface Cloneable : la classe Segment

/** Un segment est <strong>compos</strong> de deux points extrmits */


public class Segment implements Cloneable {
private Point extrmit1, extrmit2;
public Segment(Point ext1, Point ext2) {
extrmit1 = (Point) ext1.clone();
extrmit2 = (Point) ext2.clone();
}

// car composition

public Object clone() {


try {
Segment s = (Segment) super.clone();
// copie superficielle
s.extrmit1 = (Point) extrmit1.clone(); // copie de lextrmit1
s.extrmit2 = (Point) extrmit2.clone(); // copie de lextrmit2
return s;
}
catch (CloneNotSupportedException e) {
return null;
}
}
}

&

X. Crgut

Programmation objet en Java

377

'

Conclusions
Ides cls
Techniques de dcomposition et darchitecture.
Architectures logicielles flexibles et dcentralises (ni centre, ni sommet).
Construction de logiciels par combinaison ascendante (bottom-up)
dlments logiciels rutilisables.
lments partiellement affins dcrivant des comportements communs.
Spcification prcise de chaque composant (contrat logiciel).
Ouverture sur le monde extrieur : routines externes, empaquetage
doutils existants.
BIBLIOTHQUES
&

X. Crgut

Programmation objet en Java

378

'

Quest ce que la technologie objet ?


Un principe darchitecture :
MODULE = TYPE

(CLASSE)

Une discipline pistmologique :


LABSTRACTION

Une rgle de classification :


LHRITAGE (le sous-typage !)

Une exigence de validit :


LA CONCEPTION PAR CONTRAT

Une obligation dingnieur :


RUTILISABILIT ET EXTENSIBILIT

&

X. Crgut

Programmation objet en Java

379

'

Liste des exercices

Exercice 1 : quation du second degr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5


Exercice 2 : Lister les erreurs de la classe quation . . . . . . . . . . . . . . . . . . . . 9
Exercice 3 : volution de la mmoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Exercice 4 : Comparaison de rsoudre en C et Java . . . . . . . . . . . . . . . . . . . 14
Exercice 5 : Caractristiques des objets fractions . . . . . . . . . . . . . . . . . . . . . 63
Exercice 6 : Description UML de la classe Fraction . . . . . . . . . . . . . . . . . . . 71
Exercice 7 : Dfinir une date avec jour, mois et anne . . . . . . . . . . . . . . . . . 76
Exercice 8 : Suprieur et infrieur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Exercice 9 : Compteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Exercice 10 : Paramtre avec valeur par dfaut . . . . . . . . . . . . . . . . . . . . . . . 84
Exercice 11 : Surcharge des mthodes de Fraction . . . . . . . . . . . . . . . . . . . . 84
&

X. Crgut

Programmation objet en Java

380

'

Exercice 12 : Surcharge et ambigut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Exercice 13 : Comprendre le passage de paramtres en Java . . . . . . . . . . . 88


Exercice 14 : Constructeur de quation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Exercice 15 : Incrmenter le jour dune date . . . . . . . . . . . . . . . . . . . . . . . . 101
Exercice 16 : Mthode de classe ou dinstance ? . . . . . . . . . . . . . . . . . . . . . 106
Exercice 17 : Site WEB en UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Exercice 18 : Liste de rels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Exercice 19 : Sens de p.m() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Exercice 20 : Questions sur ListeTab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Exercice 21 : Formaliser le comportement de la liste . . . . . . . . . . . . . . . . . 173
Exercice 22 : Gnraliser les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Exercice 23 : changer deux lment dun tableau . . . . . . . . . . . . . . . . . . 190
&

X. Crgut

Programmation objet en Java

381

'

Exercice 24 : Plus grand lment dun tableau . . . . . . . . . . . . . . . . . . . . . . 192

Exercice 25 : Dfinition dun point nomm . . . . . . . . . . . . . . . . . . . . . . . . . 196


Exercice 26 : Dplier la classe PointNomm . . . . . . . . . . . . . . . . . . . . . . . . 211
Exercice 27 : Schmas mathmatiques : les classes abstraites . . . . . . . . . 225
Exercice 28 : Mthode retarde vs mthode redfinie . . . . . . . . . . . . . . . . 230
Exercice 29 : Dfinir un groupe dobjets gomtriques . . . . . . . . . . . . . . . 231
Exercice 30 : Dfinir un menu textuel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Exercice 31 : Pourquoi les interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Exercice 32 : Modlisation dune quipe de football . . . . . . . . . . . . . . . . . 240
Exercice 33 : Gnricit vs Hritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Exercice 34 : Gnricit et sous-typage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Exercice 35 : Afficher les lments dune liste . . . . . . . . . . . . . . . . . . . . . . 255
&
X. Crgut

Programmation objet en Java

382

'

Exercice 36 : Copier une liste dans une autre . . . . . . . . . . . . . . . . . . . . . . . 257


Exercice 37 : Tableau et sous-typage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Exercice 38 : Trajet dune exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Exercice 39 : Exception avec nombre de ressais limit . . . . . . . . . . . . . . 284
Exercice 40 : Ambigut sur lorigine dune exception . . . . . . . . . . . . . . . 294
Exercice 41 : Somme dentiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Exercice 42 : Pgcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Exercice 43 : Amliorer OutilsListe.somme . . . . . . . . . . . . . . . . . . . . . . . . . 319
&

X. Crgut

Programmation objet en Java

383

Index
]
galit, 137
logique, 137
physique, 137
numration, 147
affectation, 49
affectation renverse, 169, 219
assert, 315
attribut, 72
attributs dinstance, 72
de classe, 101, 104
principe de laccs uniforme, 76
principe de la protection en criture, 76
valeur par dfaut, 98

autodocumentation, 27
classe, 67
classe enveloppe, 142
comment la dfinir, 121
module, 67
notation UML, 70
responsabilit, 173
type, 67
vue programmeur, 115
vue utilisateur, 115
classe abstraite, 225
vs interface, 235
classe anonyme, 329
classe interne, 318
Cloneable, 375
Collection, 335
collections, 333
constructeur, 91
par dfaut, 96

surcharge, 93
this(, 94
conventions, 122
dclaration de variable, 48
dbc, voir programmation par contrat
destructeur, 100
do ... while, 54
droit daccs, 69
entres/sorties, 347
enum, voir numration
Error, 275
Exception, 275
exception, 268
conseils, 299
et redfinition, 290
et sous-typage, 289
exception utilisateur, 291

finally, 285
hors contrle, 276
lever, 281
principes, 272
propagation, 273
rcuprer, 282
sous contrle, 276
spcification, 287
throw, 281
throws, 286, 287
traiter, 283
extends, 207
final, 221
for, 55
foreach, 56
gnralisation, 206
gnricit, 179

extends, 194, 261


gnricit contrainte, 193
hritage, 241
joker, 256
mthode, 191
sous-type, 253
super, 261
wildcard, 256
hritage, voir relation dhritage
hritage multiple, 232
if, 51
import, 60
import static, 113
initialiseur, 98
InputStream, 351
instanceof, 169, 219
Integer, 143

parseInt, 144
interface, 152
exemple, 156
hritage, 234
vs classe abstraite, 235
Iterable, 346
Iterator, 345
JML, 305
old, 306
result, 306
liaison dynamique, 168, 217
liaison statique, 79
liaison tardive, voir liaison dynamique
List, 337
mthode, 77
de classe, 101, 106

exemples, 78
mthode dinstance, 77
passage de paramtre, 87
mthode abstraite, voir mthode retarde
mthode principale, 39
mthode retarde, 226
main, voir mthode principale
Map, 341
Object, 224
objet, 63
cration, 95
initialisation, 99
notation graphique, 65
old, 306
oprateur, 4346
priorit, 46
OutputStream, 352
Override, 214

paquetage, 58
paramtre implicite, voir this
passage de paramtre, 87
poigne, 64
principe de substitution, 166
programmation par contrat, 175, 300
bnfices, 303
invariant, 301
JML, voir JML
post-condition, 301
pr-condition, 301
ralisation, 160
enrichissement, 164
rsolution dun appel de mthode, 217
rutilisation, 239
Reader, 353
redfinition, 213
relation, 148

dagrgation, 149
dassociation, 149
de composition, 149
de dpendance, 148
relation dhritage, 195, 206
attribut, 222
constructeur, 210
droit daccs, 212
enrichissement, 209
interface, 234
redfinition, 213
rgle, 237
substitution, 216
surcharge, 209
vs relation dutilisation, 240
result, 306
RuntimeException, 275
sous-type, 166

spcialisation, 206
static
fabrique statique, 110
import static, 113
static, 101
String, 135
StringBuffer, 138
surcharge, 83
rsolution, 84
switch, 52
tableau, 127
plusieurs dimensions, 132
this, 80
throw, 281
Throwable, 275, 277
throws, 286, 287
toString, 82
types primitifs, 40

'

Vector, 338
visibilit, voir droit daccs

Writer, 353

while, 53

&

X. Crgut

Programmation objet en Java

384