'
Programmation objet en Java
Xavier Crgut
<cregut@[Link]>
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.
[Link]
[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.
[Link]
[7] James Gosling, Bill Joy, Guy Steele, and Gilad Bracha. The Java Language Specification.
Addison-Wesley, 3 edition, March 2005. [Link]
[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 ://[Link]/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 + [Link](delta)) / 2 / a;
double x2 = (-b - [Link](delta)) / 2 / a;
// Afficher les rsultats
[Link]("Racine 1 : " + x1);
[Link]("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
[Link] * [Link] - 4 * [Link] * [Link];
this.x1 = (- [Link] + [Link](delta)) / 2 / [Link];
this.x2 = (- [Link] - [Link](delta)) / 2 / [Link];
}
}
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
[Link]
[Link]
[Link]
coefficients
= 1;
= 5;
= 6;
// Calculer les racines de lquation
[Link]();
// Afficher les rsultats
[Link](" Racine 1 : " + unequation.x1);
[Link](" 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@[Link]>
* 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
[Link]
[Link]
[Link]
/* 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 : [Link].
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 < [Link]; i++) {
// Afficher sur la sortie standard
[Link]("Bonjour " + args[i]);
}
[Link]("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 [Link]
(==> produit [Link])
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 [Link]
---- extraits de laffichage ---[parsing started [Link]]
[checking Rsolutionquation]
[loading ./[Link]]
[parsing started ./[Link]]
[wrote [Link]]
[checking quation]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/lang/[Link])]
[wrote ./[Link]]
[total 1148ms]
&
X. Crgut
Programmation objet en Java
21
'
Compilation de [Link]
licorne> javac -verbose [Link]
[parsing started [Link]]
[parsing completed 305ms]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/lang/[Link])]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/lang/[Link])]
[checking Rsolutionquation]
[loading ./[Link]]
[parsing started ./[Link]]
[parsing completed 5ms]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/lang/[Link])]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/io/[Link])]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/io/[Link])]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/io/[Link])]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/lang/[Link])]
[wrote [Link]]
[checking quation]
[loading /opt/j2sdk1.4.0/jre/lib/[Link](java/lang/[Link])]
[wrote ./[Link]]
[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 [Link]
Exception in thread "main" [Link]: Bonjour/class
licorne> java [Link]
Exception in thread "main" [Link]: 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/[Link]:. [Link]
java -classpath /usr/local/java/junit/[Link]:. MaClasseTest
Les classes sont cherches dans [Link] puis dans le rpertoire courant.
Attention : Ne pas oublier le rpertoire courant !
En utilisant CLASSPATH avec (t)csh :
setenv CLASSPATH /usr/local/java/junit/[Link]:.
javac [Link]
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 ([Link](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++) {
[Link](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) {
[Link]("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
[Link]("i = " + i);
for (int j = 0; j < 4; j++) {
[Link]("
j = " + j);
if (j == i) {
continue premire;
// ==> passer au i suivant !
}
}
}
[Link]("Fin !");
&
X. Crgut
Programmation objet en Java
57
'
Paquetages
Programme = ensemble de classes (et interfaces) organises en paquetages.
// fichier [Link]
package [Link];
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 : [Link],
[Link]... (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 [Link]
package [Link];
public class A { ... }
class B { ... }
// fichier [Link]
package [Link];
class X { ... }
class Y { ... }
public class B { ... }
[Link]
+A
B
[Link]
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 :
[Link] c;
// La classe Color du paquetage [Link]
importer une classe (on a accs la classe sans la qualifier) :
import [Link];
...
Color c;
// en dbut de fichier
// La classe Color du paquetage [Link]
importer le contenu dun paquetage (on a accs toutes ses classes) :
import [Link].*;
...
Color c;
Point p;
// en dbut de fichier
// La classe [Link]
// La classe [Link]
Attention aux conflits si un mme nom de classe est utilis dans deux
paquetages ! Le conflit doit tre rsolu en utilisant le nom qualifi.
[Link].* 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 : [Link] 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 :
[Link]
quation unequation = new quation();
double sol1 = unequation.x1;
// accs en lecture
[Link] = 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();
[Link] = 1;
}
}
class Equation {
private double coeffA;
// ...
}
La compilation donne le rsultat suivant :
[Link]: coeffA has private access in Equation
[Link] = 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;
[Link] = 1;
}
}
La compilation donne le rsultat suivant :
[Link]: variable eq might not have been initialized
[Link] = 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;
[Link] = 1;
}
}
Lexcution donne le rsultat suivant :
Exception in thread "main" [Link]
at [Link]([Link])
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) {
[Link] = a;
[Link] = b;
[Link] = c;
}
/** Obtenir le discriminant de lquation.
* @return le discriminant de lquation
*/
private double delta() {
return [Link] * [Link] - 4 * [Link] * [Link];
}
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.
[Link](p1, ..., pn);
// Forme gnrale (envoi de message)
quation eq = new quation();
[Link](1, 5, 6);
double delta = [Link]();
[Link]();
[Link]();
// Crer un objet quation attach eq
// Initialiser lquation (mthode void)
// Utiliser une mthode non void
quation eq2 = null;
[Link](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) {
[Link] = a;
[Link] = b;
[Link] = 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 [Link]()
1
2
3
4
5
/** Afficher cette quation. */
public void afficher() {
[Link]([Link] + "*x2 + "
+ [Link] + "*x + " + [Link] + " = 0");
}
Deuxime ide : faire directement : [Link](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 "" + [Link] + "*x2 + "
+ [Link] + "*x + "
+ [Link] + " = 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)
{ [Link]("m0(i,i)"); }
{ [Link]("m1(d,d)"); }
{
{
{
{
[Link]("m2(d,d)");
[Link]("m2(d,i)");
[Link]("m2(i,d)");
[Link]("m2(i,i)");
{ [Link]("m3(d,i)"); }
{ [Link]("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
[Link](5);
// afficher(int) de la classe A
[Link](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 [Link]
public class TestParametres {
static void incrmenter(int n)
{ n++; }
static void incrmenter(Compteur cptr) { [Link](); }
static void reset(Compteur cptr)
{ cptr = new Compteur(); }
public static void main(String[] args) {
int a = 10;
incrmenter(a);
[Link]("a = " + a);
// Valeur de a ?
Compteur c = new Compteur();
[Link](10);
incrmenter(c);
[Link]("c = " + [Link]());
// valeur de c ?
reset(c);
[Link]("c = " + [Link]());
// valeur de c ?
}
}
&
X. Crgut
Programmation objet en Java
89
'
Listing 2 Le fichier [Link]
/** 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()
{ [Link]++; }
&
/** Obtenir la valeur du compteur.
* @return la valeur du compteur.
*/
public int getValeur()
{ return [Link]; }
/** Remettre zro le compteur */
public void raz()
{ [Link](0); }
/** Modifier la valeur du compteur.
* @param valeur la nouvelle valeur du compteur
*/
public void set(int valeur) { [Link] = 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) {
[Link] = a;
[Link] = b;
[Link] = 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) {
[Link] = 1;
[Link] = - somme;
[Link] = 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 :
[Link](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 :
[Link]("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 : [Link] ou [Link](...)
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 : [Link]++;
...
// 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 [Link] 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();
[Link]();
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
[Link]: non-static
referenced from a static context
i++;
^
[Link]: non-static
be referenced from a static context
this.i++;
^
[Link]: non-static
be referenced from a static context
incI();
^
[Link]: non-static
be referenced from a static context
[Link]();
^
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 [Link](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) {
[Link](1, 5, 6);
[Link](2, 1);
[Link](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 [Link]; // importe une caractristique
import static [Link].*;
// ou toutes
public class ImportationStatiqueMath {
public static void main(String[] args) {
[Link](sqrt(PI));
[Link]([Link]([Link]));
}
}
Intrt : Il est relativement faible :
crire sqrt plutt que [Link] ;
utiliser directement des constantes : RED au lieu [Link] ;
En fait, il vise viter de mauvaises pratiques : hriter (T. 195) des
classes Math ou [Link].
&
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 [Link]() == 10;
[Link]();
assert [Link]() == 11;
[Link]();
assert [Link]() == 0;
[Link](5);
assert [Link]() == 5;
}
}
Compiler : javac [Link]
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) { [Link] = valeurInitiale; }
/** Augmenter dune unit le compteur */
public void incrmenter()
{ [Link]++; }
/** Obtenir la valeur du compteur.
* @return la valeur du compteur.
*/
public int getValeur()
{ return [Link]; }
/** Remettre zro le compteur */
public void raz()
{ [Link](0); }
/** Modifier la valeur du compteur.
* @param valeur la nouvelle valeur du compteur
*/
public void set(int valeur) { [Link] = 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 :
[Link]
Rgles pour nommer :
paquetage : tout en minuscule ([Link]) ;
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 [Link]
/* 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 ([Link](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.
[Link]();
[Link]();
// 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 = [Link];
// 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 < [Link]; i++) {
= i;
tab[0];
tab[[Link]-1];
tab[[Link]];
// premier lment
// dernier lment
// ArrayIndexOutOfBoundsException
Laffectation de deux tableaux est une affectation de poigne (partage).
On peut utiliser [Link](...).
&
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 = [Link];
String[] nomJours = { "lundi", "mardi",
nb = [Link];
13 };
// nb == 5
"mercredi", ..., "dimanche" };
// nb == 7
Les tableaux ne peuvent pas tre redimensionns (length ne peut pas
changer de valeur). Voir [Link].
lexception des tableaux de caractres, laffichage par
[Link] nest pas lisible.
[Link]("nomJours = " + nomJours);
--> nomJours = [[Link];@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 < [Link]; i++) {
systme[i].rsoudre();
[Link]("quation " + (i+1) + " : ");
systme[i].afficher();
[Link]("x1 = " + systme[i].x1);
[Link]("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" [Link]
at [Link]([Link])
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) {
[Link]();
[Link]("quation : "); // sans numro !
[Link]();
[Link]("x1 = " + eq.x1);
[Link]("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 < [Link]; 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 < [Link]; i++) {
if (mat[i] == null) {
// mat[i] non allou
[Link]();
} else {
[Link](mat[i][0]);
for (int j = 1; j < mat[i].length; j++) {
[Link](", " + mat[i][j]);
}
[Link]();
}
}
}
&
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 = [Link]();
// la longueur de la chane : 7
char initiale = [Link](0);
// B
char erreur = [Link](lg);
// -> StringIndexOutOfBoundsException
// les indices sur les chanes vont de 0 length()-1.
String
String
//
//
s2 = [Link](0, 3); // "Bon"
s3 = [Link](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 = [Link]();
//
s5 = [Link]();
//
s6 = [Link](o, .);
= [Link]("on");
//
= [Link]("on", 2);
//
BONJOUR
bonjour
// [Link]
1
-1 (non trouv !)
String s7 = "Un texte
avec
des blancs";
String s8 = [Link]("\\s+", " "); // remplace blancs par espace
String[] mots = [Link]("\\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 = [Link](0, 2) == "N7";
// faux !
lgalit logique : deux chanes sont composes des mmes caractres.
boolean estN7 = [Link](0, 2).equals("N7"); // vrai !
Important : VRAI pour tout objet (toute classe), voir T. 224.
Autre comparaison logique :
int res = [Link](s2); // comparer suivant lordre lexicographique
// ngatif si s1 < s2 ; nul si [Link](s2) ; positif si s1 > s2
Rq : quivalence entre [Link](s2) et [Link](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 = [Link]();
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;
}
[Link]("Longueur de chane = " + [Link]());
}
}
public class ConcatenerStringBuffer {
public static void main(String[] args) {
StringBuffer tampon = new StringBuffer();
for (int i = 0; i < 100000; i++) {
[Link](x);
}
String chane = [Link]();
[Link]("Longueur de chane = " + [Link]());
}
}
&
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 [Link]
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 [Link].
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 = [Link]();
double d2 = [Link]();
// d2 == 100.0
int i3 = [Link]("421");
Integer n4 = [Link]("0xFFF");
// i3 == 421
// n4 == 4095
boolean test;
// test = n1 == i1;
// test = i1 == n1;
// Types incompatibles
// Types incompatibles
test = [Link]() == i1;
test = n1 == new Integer(i1);
// true
// false
// Convertir le premier paramtre de la ligne de commande.
if ([Link] > 0) {
Integer n5 = [Link](args[0]);
int i5 = [Link](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 = [Link]()
double d2 = [Link]();
// d2 == 100.0
int i3 = [Link]("421");
Integer n4 = [Link]("0xFFF");
boolean test;
test = n1 == i1;
test = i1 == n1;
// i3 == 421
// n4 == 4095
// true
// true
test = [Link]() == i1;
test = n1 == new Integer(i1);
// true
// false
// Convertir le premier paramtre de la ligne de commande.
if ([Link] > 0) {
Integer n5 = [Link](args[0]);
int i5 = [Link](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 = [Link]; break;
case ORANGE: resultat = [Link]; break;
case PRUNE: resultat = [Link]; break;
}
return resultat;
}
public static void main(String[] args) {
for (Fruit f : [Link]()) {
[Link](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, [Link]) 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();
[Link](0, 3.14);
// Quelle signification ?
}
}
[Link]: 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) {
[Link] = new double[capacite];
[Link] = 0;
// la liste est initialement vide
}
&
X. Crgut
Exemple de ralisation
public int taille() {
return [Link];
}
public double item(int index) {
return [Link][index];
}
public void remplacer(int index, double x) {
[Link][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) {
[Link]([Link], index+1,
[Link], index, [Link]-index-1);
[Link]--;
}
public void ajouter(int index, double x) {
if ([Link] >= [Link]) { // tableau trop petit !
// agrandir le tableau : pourrait tre plus efficace !
double[] nouveau = new double[[Link]+3]; // 3 arbitraire
[Link]([Link], 0, nouveau, 0, [Link]);
[Link] = nouveau;
}
// dcaler les lments partir de index
[Link]([Link], index,
[Link], index+1, [Link]-index);
// ranger le nouvel lment
[Link][index] = x;
[Link]++;
}
}
&
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();
[Link](0, 3.14);
// quel ajouter ?
[Link](0, 3.14);
// quel ajouter ?
double v1 = [Link](0);
double v2 = [Link](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 [Link][0]; }
{ return [Link][[Link] - 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 < [Link](); i++) {
resultat += [Link](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 = [Link](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;
//
//
//
//
//
???
???
???
???
???
[Link]();
[Link]();
[Link]();
[Link]()
//
//
//
//
???
???
???
???
&
X. Crgut
Programmation objet en Java
167
'
Liaison tardive (ou dynamique)
Liste l;
l = new ListeTab(9);
[Link](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
[Link](0, 3.14);
// Appel de la mthode ajouter(int, double) sur l
ListeTab lt;
lt = l;
// Interdit par le compilateur mais ncessaire pour...
[Link]();
// 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;
[Link]();
}
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 :
[Link] (interface) ;
[Link] (classe ralisant List) ;
[Link] (classe ralisant List) ;
Remarque : Il existe galement :
une classe historique [Link] proche de [Link] ;
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 ([Link], [Link]...) 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);
[Link](0, 3.14);
// quel ajouter ?
[Link](0, 3.14);
// quel ajouter ?
[Link](0, "PI");
[Link](0, l1);
[Link](1, l2);
double v1 = [Link](0);
double v2 = [Link](1).item(0);
String vs = [Link](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_) {
[Link] = premier_;
[Link] = second_;
}
}
import [Link];
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");
[Link] = [Link];
[Link] = [Link];
Couple<Color, String> p3 =
new Couple<Color, String> ([Link], "rouge");
[Link] = "VERT";
[Link] = [Link];
&
X. Crgut
Programmation objet en Java
185
'
Rsultat de la compilation de TesterCoupleErreur
1
2
3
4
5
6
7
8
9
10
11
[Link]: incompatible types
found
: [Link]
required: [Link]
[Link] = "VERT";
^
[Link]: incompatible types
found
: [Link]
required: [Link]
[Link] = [Link];
^
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_) {
[Link] = element_;
[Link] = suivante_;
}
public Cellule<T> getSuivante() {
return [Link];
}
public T getElement() {
return [Link];
}
public void setElement(T nouveau) {
[Link] = nouveau;
}
&
X. Crgut
public void setSuivante(Cellule<T> s) {
[Link] = 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 [Link];
}
/** 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 = [Link];
for (int i = 0; i < index; i++) {
curseur = [Link]();
}
return curseur;
}
public T item(int index) {
return [Link](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
[Link] = new Cellule<T>(x, [Link]);
} else {
// insertion aprs une cellule
Cellule<T> precedente = cellule(index-1);
Cellule<T> nouvelle = new Cellule<T>(x,
[Link]());
[Link](nouvelle);
}
[Link]++;
// une cellule ajoute
}
&
X. Crgut
[Link](index).setElement(x);
public void supprimer(int index) {
if (index == 0) {
// insertion en tte
[Link] = [Link]();
} else {
// insertion aprs une cellule
Cellule<T> precedente = cellule(index-1);
[Link]([Link]().getSuivante());
}
[Link]--;
// 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 || [Link](x) < 0) {
resultat = x;
}
}
return resultat;
}
/** Programme de test de [Link] */
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 ([Link]) :
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() {
[Link]("(" + this.x + "," + this.y + ")");
}
public double distance(Point autre) {
double dx2 = [Link](autre.x - this.x, 2;
double dy2 = [Link](autre.y - this.y, 2;
return [Link](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 [Link] dans [Link]
cp [Link] [Link]
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) {
[Link] = new Point(vx, vy);
[Link] = nom;
}
public double getX()
public double getY()
public String getNom()
{ return [Link](); }
{ return [Link](); }
{ return [Link]; }
public void translater(double dx, double dy) {
[Link](dx, dy);
}
public void afficher()
&
X. Crgut
Le code Java correspondant
{ [Link](); }
public double distance(PointNomme autre) {
return [Link]([Link]);
}
...
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) {
[Link](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)
[Link]();
// (1,2) mthode de Point
[Link](-1, 2);
//
mthode de Point
[Link]();
// (0,4) mthode de Point
[Link]("B");
// mthode de PointNomme
String n = [Link](); // mthode de PointNomme
[Link]("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() {
[Link](getNom() + ":");
[Link]();
// 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.
[Link]();
// 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
[Link]: method does not override or implement a
method from a supertype
@Override
^
[Link]: 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; [Link](); // ?????
q = pn1; [Link](); // ?????
PointNomme qn; // poigne sur un PointNomm
qn = p1; [Link](); // ?????
qn = pn1; [Link](); // ?????
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; [Link](); // (3,4)
q = pn1; [Link](); // A:(30,40)
PointNomme qn; // poigne sur un Point
qn = p1; [Link](); // INTERDIT !
qn = pn1; [Link](); // 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)
[Link]()
// ????
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;
[Link]("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();
[Link]("a.attr1 = "
[Link]("b.attr1 = "
[Link]("a.attr2 = "
[Link]("b.attr2 = "
[Link]("b.attr2 = "
[Link]("c.attr2 = "
[Link]("((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 [Link](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 [Link] couleur;
// couleur de lobjet
/** Construire un objet gomtrique.
* @param c la couleur de lobjet gomtrique */
public ObjetGomtrique([Link] c)
{ [Link] = c; }
/** Obtenir la couleur de cet objet.
* @return la couleur de cet objet */
public [Link] getCouleur()
/** Changer la couleur de cet objet.
* @param c nouvelle couleur */
public void setCouleur([Link] c)
{ return [Link]; }
{ [Link] = 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 ?
[Link]("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 ; }
/** Strictement suprieur (greater than) */
final public boolean gt(T a)
{ return [Link](this); }
/** Infrieur ou gal (lesser equal) */
final public boolean le(T a)
{ return ; }
final public boolean equals(T a)
{ return  && ; }
}
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++) {
[Link](new Point(i, i));
}
while (![Link]()) {
[Link]().afficher();
[Link]();
}
}
}
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++) {
[Link](new Point(i, i));
}
while (![Link]()) {
((Point)[Link]()).afficher();
[Link]();
}
}
}
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++) {
[Link](new Point(i, i));
}
while (![Link]()) {
[Link]().afficher();
[Link]();
}
}
}
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) [Link]();
}
private PileFixeObject points;
public void empiler(Point elt) {
[Link](elt);
}
public PileFixePoint(int capa) {
points =
new PileFixeObject(capa);
}
public boolean estVide() {
return [Link]();
public void dpiler() {
[Link]();
}
}
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 = [Link];
// 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;
[Link](0, "texte");
[Link](0, 15.5);
// en fait new Double(15.5);
String s = [Link](0);
[Link](s);
}
}
[Link]: incompatible types
found
: ListeTab<[Link]>
required: ListeTab<[Link]>
ListeTab<Object> lo = ls;
^
Note: ./[Link] 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 < [Link](); i++) {
[Link]([Link](i));
}
}
public static void main(String[] args) {
Liste<Object> lo = new ListeTab<Object> (5);
[Link](0, "deux");
[Link](0, "un");
afficher(lo);
Liste<String> ls = new ListeTab<String> (5);
[Link](0, "deux");
[Link](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 < [Link](); i++) {
[Link]([Link](i));
}
}
Une meilleure solution consiste utiliser un type joker (wildcard) : <?> :
static void afficher(Liste<?> ll) {
for (int i = 0; i < [Link](); i++) {
[Link]([Link](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) {
[Link]([Link](), 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) {
[Link]([Link](), 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 [Link] >= [Link]
: "Capacit insuffisante : " + [Link]
+ " < " + [Link];
for (int i = 0; i < [Link]; i++) {
destination[i] = source[i];
}
}
public static void main(String[] args) {
String[] tab1 = { "un", "deux", "trois" };
String[] tab2 = new String[[Link]];
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" [Link]:
[Link]
at [Link]([Link])
at [Link]([Link])
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 < [Link](); i++) {
[Link]([Link](), [Link](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 < [Link](); i++) {
[Link]([Link](), [Link](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 < [Link](); i++) {
[Link]([Link](), [Link](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 < [Link](); i++) {
[Link]([Link](), [Link](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 [Link].*;
// 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 = [Link]()) != null) {
somme += [Link](ligne);
nb++;
}
[Link]();
[Link]("Moyenne = " + (somme / nb));
} catch (IOException e) {
[Link]("Problme dE/S : " + e);
[Link]();
} catch (NumberFormatException e) {
[Link]("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 : [Link]: quinze
> java Moyenne
# pas de fichier en argument
Exception in thread "main"[Link]
at [Link]([Link])
> java Moyenne Donnes4
# fichier contenant des lignes vides
Une donne non numrique : [Link]: empty String
> java Moyenne Donnes5
# fichier inexistant
Problme dE/S : [Link]: Donnes5 (Aucun fichier
ou rpertoire de ce type)
[Link]: Donnes5 (No such file or directory)
at [Link](Native Method)
at [Link].<init>([Link])
at [Link].<init>([Link])
at [Link].<init>([Link])
at [Link]([Link])
> 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" [Link]: / by zero
at ExceptionPropagation.m3([Link])
at ExceptionPropagation.m2([Link])
at ExceptionPropagation.m1([Link])
at [Link]([Link])
&
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 [Link] : ce sont des erreurs non
accessibles, qui ne peuvent gnralement pas tre rcupres
(OutOfMemoryError, AssertionError, NoClassDefFoundError...) ;
classes drives de [Link] : 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 [Link] ni [Link]. Exemples :
[Link], 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 [Link]
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 [Link] et [Link]
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 [Link]
[Link]
[Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
[Link]
[Link]
+-- [Link]
+-- [Link]
+-- [Link]
+-- [Link]
&
X. Crgut
Programmation objet en Java
278
'
Extrait des descendants de [Link]
[Link]
[Link]
[Link]
[Link]
+-- [Link]
+-- [Link]
[Link]
[Link]
[Link]
+-- [Link]
+-- [Link]
[Link]
[Link]
[Link]
[Link]
&
X. Crgut
Programmation objet en Java
279
'
Extrait des autres descendants de Exception
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
&
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 [Link](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 ? e==null : [Link](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 [Link];
class A {
void m1() {
FileReader f = new FileReader("[Link]");
}
}
Rsultat de la compilation
[Link]: unreported exception
[Link]; must be caught or declared to be
thrown
FileReader f = new FileReader("[Link]");
^
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 { };
[Link]: m() in B1 cannot override m() in
A; overridden method does not throw E1
void m() throws E1 { };
^
[Link]: 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 [Link](x);
}
public static void main (String args []) {
try {
double d = [Link]("Donnez un rel : ");
[Link]("RC(" + d + ") = " + RC(d));
for (int i = 0; i < 10; i++) {
[Link]("RC(" + i*i + ") = " + RC(i*i));
}
} catch (MathException e) {
[Link]("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 = [Link]("Numrateur : ");
int d = [Link]("Dnominateur : ");
f = new Fraction(n, d);
[Link]("f = ");
[Link]();
[Link]("inverse de f = ");
[Link]().afficher();
}
catch (DivisionParZeroException e) {
[Link]("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 < [Link]; i++) {
somme += [Link](args[i]);
}
[Link]("Somme : " + somme);
}
catch (FormatEntierException e) {
[Link]("Caractre interdit : >"
+ [Link]()
+ "< la position " + [Link]()
+ " de " + [Link]());
}
}
}
&
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");
[Link] = chaine;
[Link] = indice;
}
/** La chane contenant lentier en base 10 */
public String getChaine() { return [Link]; }
/** Position du premier caractre interdit (1 si cest le premier) */
public int getPositionErreur() { return [Link] + 1; }
/** Premier caractre erron. */
public char getCaractereErrone() { return [Link]([Link]); }
public String toString() {
return "FormatEntierException: Erreur dans " + [Link]
+ " la position " + ([Link]+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 < [Link](); i++) {
char c = [Link](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 [Link](x);
}
// x positif
// la racine carre est positive
// son carr est x
public static void main (String args []) {
double d = [Link]("Donnez un rel : ");
if (d >= 0) {
// test explicite !!!
[Link]("RC(" + d + ") = " + RC(d));
}
for (int i = 0; i < 10; i++) {
[Link]("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 < [Link]; tab[i] > 0);
// tous les lments de tab sont strictement positifs
(\exists int i; i >= 0 && i < [Link]; 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 [Link](x * \result - 1) <= EPSILON;
//@ ensures [Link](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 [Link];
}
//@ ensures getValeur() == \old(getValeur()) + 1;
public void incrementer() {
[Link]++;
}
}
&
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 [Link](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 \[Link]() == - getNumerateur();
//@ ensures \[Link]() == 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 \[Link](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 \[Link](new Fraction(num * [Link], den * [Link]));
public /*@ pure @*/ Fraction produit(Fraction autre) {
return new Fraction(num * [Link], den * [Link]);
}
/** galit logique entre fractions. */
//@ ensures \result == ((getNumerateur() == [Link]()
//@
&& getDenominateur() == [Link]()));
public /*@ pure @*/ boolean equals(Fraction autre) {
return num == [Link] && den == [Link];
}
/** Afficher la fraction. */
public void afficher()
{
[Link](getNumerateur());
if (getDenominateur() > 1) {
[Link]("/" + getDenominateur());
}
}
}
&
X. Crgut
Programmation objet en Java
311
'
Programmation par contrat : utilisation de Fraction
public class TestFractionDBC {
public static void main (String args []) throws [Link] {
int n, d;
// numrateur et dnominateur dune fraction
do {
n = [Link]("Numrateur : ");
d = [Link]("Dnominateur : ");
if (d == 0)
[Link]("Le dnominateur doit tre > 0 !");
} while (d == 0);
Fraction f = new Fraction(n, d);
[Link]("La fraction est : ");
[Link]();
[Link]();
if ([Link]() != 0) {
[Link]("Son inverse est : ");
[Link]().afficher();
[Link]();
}
}
}
&
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 = [Link](x);
assert result >= 0 : result;
assert result * result == x : result;
return result;
}
public static void main (String args []) {
double d = [Link]("Donnez un rel : ");
if (d >= 0) {
// test explicite !!!
[Link]("RC(" + d + ") = " + RC(d));
}
for (int i = 0; i < 10; i++) {
[Link]("RC(" + i*i + ") = " + RC(i*i));
}
// Attention, sans test !!!
[Link]("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 [Link]
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" [Link]: x ngatif -4.0
at [Link](RC_assert.java:4)
at [Link](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 [Link]
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 < [Link](); i++) {
resultat += [Link](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 = [Link]();
while ([Link]()) {
resultat += [Link]();
}
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) {
[Link] = elts;
[Link] = taille;
[Link] = 0;
}
public boolean encore() {
return [Link] < [Link];
}
public double suivant() {
return [Link][[Link]++];
}
&
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) {
[Link] = l;
[Link] = 0;
}
public boolean encore() {
return [Link] < [Link];
}
public T suivant() {
return [Link][[Link]++];
}
&
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() {
[Link] = 0;
}
public boolean encore() {
return [Link] < [Link];
// accs lattribut nb de lobjet englobant
}
public T suivant() {
return elements[[Link]++];
// implicitement [Link]
}
&
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 = [Link]();
// it est construit partir de ll
ListeTab<Double> lt = ...;
Iterateur<Double> it2 = [Link] 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 [Link] < nb;
}
};
public T suivant() {
return elements[[Link]++];
}
// 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 ([Link]. 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 [Link]
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 [Link]<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 [Link]<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 [Link]<E>
Objectif : Disposer de tableaux automatiquement redimensionnables.
Remarque : La classe Vector est dfinie dans le paquetage [Link].
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 [Link] (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<[Link]<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 [Link];
import [Link];
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 ([Link](s)) {
[Link](s, 1 + [Link](s));
} else {
[Link](s, 1);
}
}
[Link]("occ = " + occ);
[Link]("cls = " + [Link]());
[Link]("valeurs = " + [Link]());
[Link]("entres = " + [Link]());
// afficher chaque entre
for ([Link]<String, Integer> e : [Link]()) {
[Link]([Link]() + " --> " + [Link]());
}
&
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 [Link]<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 = [Link]();
while ([Link]()) {
Double lment = [Link](); // retourne llment courant et avance
// manipuler lment...
}
Inspiration : Analogie avec le parcours dun tableau.
&
X. Crgut
Programmation objet en Java
345
'
Linterface [Link]<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 = [Link]();
while ([Link]()) {
E o = [Link]();
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 [Link]. 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, [Link])
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, [Link])
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 = [Link]();
while (c != -1) {
[Link](c);
c = [Link]();
}
[Link]();
[Link]();
}
&
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 = [Link](tampon)) > 0) {
[Link](tampon, 0, nb);
}
[Link]();
[Link]();
}
&
X. Crgut
Programmation objet en Java
358
'
La classe [Link]
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 [Link];
public class Lister {
public static void lister(File file) {
[Link]([Link]());
if (![Link]()) {
[Link](": fichier ou rpertoire inexistant !");
} else if ([Link]()) {
[Link](":");
lister(file, [Link]());
[Link]();
}
else {
if ([Link]()) {
[Link]("*");
}
[Link]();
}
}
&
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 [Link].*;
public class FlipCaseInputStream extends FilterInputStream {
public FlipCaseInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int c = [Link]();
// idem [Link]()
int newC = c;
if ([Link](c)) {
newC = [Link](c);
} else if ([Link](c)) {
newC = [Link](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 [Link].*;
public class TestFlipCaseInputStream {
public static void afficher(InputStream in) throws IOException {
int c;
while ((c = [Link]()) != -1) {
[Link]((char) c);
}
}
public static void main(String[] args) throws IOException {
InputStream inStream = new FlipCaseInputStream(
new FileInputStream(args[0]));
afficher(inStream);
[Link]();
}
}
&
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 [Link].*;
public class TestFiltres {
public static void main(String[] args) throws IOException {
DataOutputStream dos =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("/tmp/[Link]")));
[Link](12.5);
[Link]("Dupond");
[Link](421);
[Link]();
}
}
&
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 [Link].*;
import [Link];
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 = [Link]()) != -1) {
[Link](c);
}
[Link]();
[Link]();
}
&
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 [Link].*;
import [Link].*;
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
[Link](new ZipEntry(nom));
InputStream entree = new FileInputStream(nom);
int c;
while ((c = [Link]()) != -1) {
[Link](c);
}
[Link]();
[Link]();
}
[Link]();
}
&
X. Crgut
Exemple : Compresser une archive Zip
public static void main(String[] args) throws IOException {
zipper("/tmp/[Link]", 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 [Link].*;
import [Link].*;
public class Dezipper {
public static void main(String[] args) throws IOException {
ZipInputStream zin = new ZipInputStream(
new FileInputStream(args[0]));
ZipEntry entree = [Link]();
while (entree != null) {
String nomEntree = "/tmp/" + [Link]();
FileOutputStream out = new FileOutputStream(nomEntree);
[Link](out, zin);
[Link]();
[Link]();
entree = [Link]();
}
[Link]();
}
}
&
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 [Link] {
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([Link]));
&
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 [Link](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 [Link]();
// une copie superficielle suffit !
} catch (CloneNotSupportedException e) {
return null; // ne peut pas se produire car implements Cloneable
}
}
}
Remarque : Implmenter Cloneable autorise faire [Link]() !
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) [Link]();
extrmit2 = (Point) [Link]();
}
// car composition
public Object clone() {
try {
Segment s = (Segment) [Link]();
// copie superficielle
s.extrmit1 = (Point) [Link](); // copie de lextrmit1
s.extrmit2 = (Point) [Link](); // 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 [Link] . . . . . . . . . . . . . . . . . . . . . . . . . 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