Académique Documents
Professionnel Documents
Culture Documents
Xavier Crgut
<cregut@enseeiht.fr>
Octobre 2009
&
X. Crgut
'
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
'
Rfrences
[1] Cay S. Horstmann and Gary Cornell. Au cur de Java 2, volume 1 Notions
fondamentales. Campus Press, 8 edition, 2008.
[2] Bruce Eckel. Thinking in Java. Prentice-Hall, 3 edition, 2002.
http://www.mindviewinc.com/Books/.
[3] Joshua Bloch. Java efficace. Vuibert, 2002.
[4] David Flanagan. Java en concentr. OReilly, 5 edition, 2006.
[5] Mark Grand. Patterns in Java : A Catalog of Reusable Design Patterns Illustrated with
UML, volume 1. Wiley, 2 edition, 2002.
[6] Sun. The Source for Java Technology.
http://java.sun.com.
[7] James Gosling, Bill Joy, Guy Steele, and Gilad Bracha. The Java Language Specification.
Addison-Wesley, 3 edition, March 2005. http://java.sun.com/docs/books/jls/.
[8] Bertrand Meyer. Object-oriented software construction. Prentice Hall, 2nd edition, 1997.
[9] Pierre-Alain Muller and Nathalie Gaertner. Modlisation objet avec UML. Eyrolles, 2
edition, 2003.
[10] Martin Fowler. UML 2.0. CampusPress Rfrence, 2004.
&
X. Crgut
'
Plan du cours
&
X. Crgut
'
&
X. Crgut
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
&
X. Crgut
'
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
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
X. Crgut
'
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
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Rsolutionquation {
/** Rsoudre une quation du second degr. */
public static void main (String[] args) {
quation unequation;
// une poigne sur une quation
unequation = new quation();
// cration dun objet quation
// Initialiser les
unequation.coeffA
unequation.coeffB
unequation.coeffC
coefficients
= 1;
= 5;
= 6;
X. Crgut
10
'
Quelques constatations
X. Crgut
11
'
&
X. Crgut
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
/*******************************************************************
* Objectif : Modlisation dune quation du second degr
et de sa rsolution.
*
: Xavier CRGUT <cregut@enseeiht.fr>
* Auteur
* Version : 1.2
******************************************************************/
#ifndef EQUATION__H
#define EQUATION__H
/* Dfinition du type Equation */
struct Equation {
double coeffA, coeffB, coeffC; /* coefficients de lquation */
double x1, x2;
/* racines de lquation */
};
typedef struct Equation Equation;
/* Dterminer les racines de lquation du second degr.
void resoudre(Equation *eq);
&
X. Crgut
#endif
*/
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;
}
X. Crgut
14
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>
#include "equation.h"
int main()
{
Equation uneEquation;
/* Initialiser les
uneEquation.coeffA
uneEquation.coeffB
uneEquation.coeffC
/* notre quation */
coefficients */
= 1;
= 5;
= 6;
&
X. Crgut
return EXIT_SUCCESS;
15
'
De nouvelles constatations
On peut avoir une approche objet mme avec un langage non objet !
Attention : On naura pas tous les bnfices dune approche objet...
sauf faire des choses trs (trop !) compliques.
Dans la version C, il y a sparation entre la spcification (interface) et
limplantation (corps) du module alors quen Java tout est dans une
mme construction syntaxique (la classe), dans un seul fichier.
La fonction resoudre est lextrieur de lenregistrement.
Le paramtre eq de rsoudre a disparu en Java. Il est devenu implicite.
Pour y faire rfrence, on utilise le mot-cl this.
Dans la version C, on utilise #include <math.h>.
En Java, on indique o se trouve llment utilis : Math.sqrt.
Voir aussi CLASSPATH (T. 28). et import (T. 60)
Le new de Java correspondrait un malloc en C. En Java, la mmoire est
libre automatiquement (pas de delete ou free).
&
X. Crgut
16
'
&
X. Crgut
17
'
&
X. Crgut
18
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
&
X. Crgut
19
'
X. Crgut
20
'
Le compilateur : javac
&
X. Crgut
21
'
Compilation de Rsolutionquation.java
&
X. Crgut
22
'
Le code produit par javac tant du code intermdiaire, il ne peut pas tre
directement excut par la machine.
= Il faut donc utiliser une machine virtuelle Java : java dans le JDK :
licorne> java Bonjour Xavier
Bonjour Xavier
Bonjour tout le monde !
On donne en paramtre une classe Java (donc sans extension !) qui doit
contenir la mthode principale main, suivi des ventuels arguments de la
ligne de commande.
Attention : Ne pas mettre dextension derrire le nom de la classe.
licorne> java Bonjour.class
Exception in thread "main" java.lang.NoClassDefFoundError: Bonjour/class
licorne> java Bonjour.java
Exception in thread "main" java.lang.NoClassDefFoundError: Bonjour/java
X. Crgut
23
'
24
'
&
X. Crgut
Documentation engendre
25
'
Les commentaires
&
X. Crgut
26
'
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.
/**
*
*
*
*/
&
X. Crgut
27
'
Par dfaut, les outils du JDK cherchent les classes dans le rpertoire courant.
Si les classes sont dans plusieurs rpertoires, on utilise le classpath :
soit avec loption -classpath des outils du JDK ;
soit avec la variable denvironnement CLASSPATH.
Remarque : Ncessaire ds quon utilise des bibliothques (JUnit,
Log4J...) qui sont dans des rpertoires ou fichiers darchive (.jar) propres.
javac -classpath /usr/local/java/junit/junit.jar:. MaClasseTest.java
java -classpath /usr/local/java/junit/junit.jar:. MaClasseTest
Les classes sont cherches dans junit.jar puis dans le rpertoire courant.
Attention : Ne pas oublier le rpertoire courant !
En utilisant CLASSPATH avec (t)csh :
setenv CLASSPATH /usr/local/java/junit/junit.jar:.
javac MaClasseTest.java
java MaClasseTest
&
X. Crgut
28
'
&
X. Crgut
29
'
X. Crgut
30
'
31
'
X. Crgut
32
'
&
X. Crgut
33
'
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
34
'
X. Crgut
35
'
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
36
'
Origine et historique
X. Crgut
37
'
Algorithmique en Java
&
X. Crgut
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) {
...
}
39
'
40
'
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
float
32
0.0
IEEE 754
IEEE 754
double
64
0.0
IEEE 754
IEEE 754
boolean
false
false
true
char
16
\u0000
\u0000
\uFFFF
a, \n, \
&
X. Crgut
// OK : conversion (coersion)
// Erreur de compilation !
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
42
'
Oprateurs relationnels
==
!=
>
>=
<
<=
//
//
//
//
//
//
3
4
4
4
3
3
== 3
!= 5
> 3
>= 3
< 4
<= 4
Oprateurs arithmtiques
+ * /
%
+
++
--
&
X. Crgut
//
//
//
//
//
//
//
43
'
// ET logique
// OU logique
// NON logique
&
X. Crgut
est quivalent
est quivalent
A
!A
44
'
//
//
//
//
//
//
//
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)
45
'
1G
2D
3D
4G
5G
6G
7G
8G
9G
10G
11G
12G
13G
14D
15D
a + b + c + d
x = y = z = t
&
X. Crgut
46
'
X. Crgut
47
'
// 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
&
X. Crgut
48
'
i, j, k;
2;
i * (i - 1);
k = i+j;
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 ?
49
'
&
X. Crgut
// instruction compose
nbAnnes++;
capital = capital * (1 + taux);
50
'
Conditionnelles : if
if (<condition>)
<instruction>;
if (<condition>) {
<instructions1 >;
} else {
<instructions2 >;
}
if (n1 == n2) {
res = "gaux";
} else {
res = "diffrents";
}
51
'
switch (<expression>) {
case <expr_cste1 >:
<instructions1 >;
break;
...
case <expr_csten >:
<instructionsn >;
break;
default:
<instruction>;
}
X. Crgut
52
'
Rptitions : while
while (<condition>) {
<instructions>;
}
53
'
do {
<instructions>;
} while (<condition>);
54
'
Rptitions : for
Smantique : <init> (initialisation) est excute puis, tant que <cond> est
vraie <instructions> et <incr> (incrmentation) sont excutes.
{
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
55
'
Rptitions : foreach
for (<type> <var> : <col>) {
<instructions>;
}
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
56
'
&
X. Crgut
57
'
Paquetages
// paquetage dappartenance
// texte Java de la classe
&
X. Crgut
58
'
un.premier.paquetage
+A
B
un.deuxieme.paquetage
import
X
Y
+B
Une classe dclare publique (public) peut tre utilise depuis dautres
paquetages sinon elle est locale au paquetage.
On peut mettre plusieurs classes dans un mme fichier Java (dconseill)
mais une seule peut tre publique (elle donne son nom au fichier).
X. Crgut
59
'
// en dbut de fichier
// La classe Color du paquetage java.awt
// en dbut de fichier
// La classe java.awt.Color
// La classe java.awt.Point
Attention aux conflits si un mme nom de classe est utilis dans deux
paquetages ! Le conflit doit tre rsolu en utilisant le nom qualifi.
java.lang.* est import par dfaut : il contient les classes de base, les
classes System, Math, String, etc.
&
X. Crgut
60
'
Paquetage : intrts
61
'
Les objets
Les poignes
Les classes
Les attributs
Les mthodes
Les constructeurs
Les attributs et mthodes de classe
&
X. Crgut
62
'
Les objets
&
X. Crgut
63
'
Les poignes
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();
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();
64
'
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
rsoudre()
mthodes
&
X. Crgut
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
66
'
Les classes
&
X. Crgut
67
'
68
'
Droit daccs/Visibilit
public
protected
dfaut
private
La mme classe
oui
oui
oui
oui
oui
oui
oui
non
oui
oui
non
non
oui
non
non
non
X. Crgut
69
'
nom de la classe
attributs
+mthodePublique
mthodePrive(a: double): int
#mthodeProtge(a:int, b:int)
oprations (UML)
mthodes (Java)
&
X. Crgut
- #
correspondant
%
70
'
+coeffA: double
+coeffB: double
+coeffC: double
+x1: double
+x2: double
+rsoudre()
X. Crgut
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;
poigne.attribut
X. Crgut
72
'
1
2
3
4
5
6
7
8
9
10
class TestEquationErreur1 {
public static void main(String[] args) {
Equation eq = new Equation();
eq.coeffA = 1;
}
}
class Equation {
private double coeffA;
// ...
}
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
73
'
class TestEquationErreur2 {
public static void main(String[] args) {
Equation eq;
eq.coeffA = 1;
}
}
X. Crgut
74
'
class TestEquationErreur3 {
public static void main(String[] args) {
Equation eq = null;
eq.coeffA = 1;
}
}
&
X. Crgut
75
'
&
X. Crgut
76
'
Mthodes
&
X. Crgut
77
'
Mthodes : exemples
Remarque : delta() est private car elle na pas tre utilise de lextrieur.
&
X. Crgut
78
'
Mthodes : utilisation
Une mthode est toujours applique sur une poigne (comme un attribut) et
est excute sur lobjet associ cette poigne.
poigne.mthode(p1, ..., pn);
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
79
'
Rq :
this
&
X. Crgut
80
'
X. Crgut
81
'
+ 5.0*x + 6.0 = 0
82
'
Surcharge
&
X. Crgut
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
//
//
//
//
//
//
//
X. Crgut
84
'
Exemples de surcharge
void
void
void
void
m2(double
m2(double
m2(int a,
m2(int a,
a, double b)
a, int b)
double b)
int b)
{ System.out.println("m0(i,i)"); }
{ System.out.println("m1(d,d)"); }
{
{
{
{
System.out.println("m2(d,d)");
System.out.println("m2(d,i)");
System.out.println("m2(i,d)");
System.out.println("m2(i,i)");
{ System.out.println("m3(d,i)"); }
{ System.out.println("m3(i,d)"); }
&
}
X. Crgut
}
}
}
}
m3(1, 1);
m3(2, 2.0);
m3(3.0, 3);
m3(4.0, 4.0);
85
'
class B {
/** afficher nb fois */
void afficher(int nb);
}
X. Crgut
86
'
X. Crgut
87
'
&
X. Crgut
88
'
$
Listing 1 Le fichier TestParametres.java
// Valeur de a ?
// valeur de c ?
reset(c);
System.out.println("c = " + c.getValeur());
// valeur de c ?
}
}
&
X. Crgut
89
'
&
{ return this.valeur; }
{ this.set(0); }
X. Crgut
90
'
Constructeurs
&
X. Crgut
91
'
&
X. Crgut
92
'
Constructeur et surcharge
&
X. Crgut
93
'
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 !
}
X. Crgut
94
'
// OK
+ 5x + 6
2
// OK
x - 2x + 1
// Incorrect !
// Incorrect !
&
X. Crgut
95
'
&
X. Crgut
96
'
&
X. Crgut
97
'
&
X. Crgut
98
'
99
'
Destructeurs
100
'
&
X. Crgut
101
'
// racine carre de 4
sqrt(double) est bien une mthode mais elle nest pas applique un objet
mais la classe Math. Cest une mthode de classe.
On constate que sqrt(double) travaille exclusivement sur son paramtre.
Que penser de linstruction suivante :
System.out.println("Que suis-je ?");
out est un attribut (puisquil nest pas suivi de parenthses) mais il est
appliqu une classe (System). Cest parce quil nest pas spcifique dun
objet particulier : la sortie standard est la mme pour tout le monde !
Cest en fait un attribut de classe.
&
X. Crgut
102
'
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) {}
}
103
'
Attribut de classe
// initialisation explicite
X. Crgut
104
'
{
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
X. Crgut
105
'
Mthodes de classe
&
X. Crgut
106
'
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
&
X. Crgut
107
'
Le rsultat de la compilation :
1
2
3
4
5
6
7
8
9
10
11
12
13
MethodeClasseAccesMembres.java:14: non-static
referenced from a static context
i++;
^
MethodeClasseAccesMembres.java:15: non-static
be referenced from a static context
this.i++;
^
MethodeClasseAccesMembres.java:16: non-static
be referenced from a static context
incI();
^
MethodeClasseAccesMembres.java:17: non-static
be referenced from a static context
this.incI();
^
4 errors
&
X. Crgut
variable i cannot be
108
'
&
X. Crgut
109
'
Fabrique statique
110
'
main(String[] arguments) {
Equation.depuisCoefficients(1, 5, 6);
Equation.depuisSommeEtProduit(2, 1);
Equation.depuisRacines(2, 1);
&
X. Crgut
111
'
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
112
'
Importation statique
&
X. Crgut
113
'
lments mthodologiques
&
X. Crgut
114
'
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
115
'
{ ... }
{ ... }
{ ... }
116
'
{ ... }
{ ... }
{ ... }
117
'
3. Programme de test
1
2
3
4
5
6
7
8
9
10
11
12
class TestCompteur {
public static void main(String[] args) {
Compteur c = new Compteur(10);
assert c.getValeur() == 10;
c.incrmenter();
assert c.getValeur() == 11;
c.raz();
assert c.getValeur() == 0;
c.set(5);
assert c.getValeur() == 5;
}
}
&
X. Crgut
118
'
Compteur
valeur : int
+ getValeur() : int
+ raz
+ incrmenter
+ set(valeur : int)
+ Compteur(valeur : int)
{ ... }
{ ... }
{ ... }
&
X. Crgut
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
{ return this.valeur; }
{ this.set(0); }
&
X. Crgut
5. crire le code
120
'
121
'
122
'
package ...;
import ...;
/**
* Commentaire de documentation de la classe
* @version
Prnom Nom
* @author
*/
public class MaClasse { // ==> Le fichier est MaClasse.java
/* commentaire dimplmentation de la classe */
// variables (attributs) de classe
// variables (attributs) dinstance
// constructeurs
// mthodes.
//
&
X. Crgut
123
'
// sa documentation
&
X. Crgut
124
'
// 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;
125
'
prfrer
if (condition) {
return true;
} else {
return false;
}
return condition;
if (condition) {
return x;
}
return y;
&
X. Crgut
126
'
Les tableaux
Les tableaux en Java se rapprochent beaucoup des objets :
ils sont accessibles par une poigne ;
int[] tab1;
int tab2[];
Type[] tab;
&
X. Crgut
127
'
// premier lment
// dernier lment
// ArrayIndexOutOfBoundsException
&
X. Crgut
128
'
13 };
// nb == 5
"mercredi", ..., "dimanche" };
// nb == 7
&
X. Crgut
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
&
X. Crgut
130
'
Rsultat de lexcution
&
X. Crgut
131
'
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
&
X. Crgut
132
'
//
Le triangle de Pascal
// Crer le tableau de lignes
int[][] triangle = new int[10][];
// Construire la premire ligne
triangle[0] = new int[2];
triangle[0][0] = triangle[0][1] = 1;
// Construire les autres lignes
for (int i = 1; i < triangle.length; i++) {
// Cration de la (i+1)me ligne du triangle
triangle[i] = new int[i+2];
triangle[i][0] = 1;
for (int j = 1; j < triangle[i].length - 1; j++) {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
triangle[i][i+1] = 1;
}
afficher(triangle);
&
X. Crgut
133
'
&
X. Crgut
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 =
X. Crgut
// 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
String
String
String
int p1
int p2
s4 = s1.toUpperCase();
//
s5 = s1.toLowerCase();
//
s6 = s1.replace(o, .);
= s1.indexOf("on");
//
= s1.indexOf("on", 2);
//
BONJOUR
bonjour
// B.nj.ur
1
-1 (non trouv !)
&
X. Crgut
136
'
// faux !
== 0 !
137
'
La classe StringBuffer
Un StringBuffer est une chane de caractres (comme String ) qui
peut tre modifie !
En plus de la majorit des mthodes de String, StringBuffer propose
append : ajouter la fin de la chane ;
insert : ajouter une position spcifie de la chane.
Ces deux mthodes sont largement surcharges !
Passage de String StringBuffer et inversement :
StringBuffer t1 = new StringBuffer("Bonjour");
StringBuffer t2 = new StringBuffer();
// Chane de longueur 0 !
String s2 = t1.toString();
StringBuffer t3 = new StringBuffer(s2);
StringBuffer t4 = "toto";
// Interdit !
&
X. Crgut
138
'
&
X. Crgut
139
'
&
X. Crgut
140
'
String ou StringBuffer ?
Temps dexcution :
> time java ConcatenerString
Longueur de chane = 100000
real 1335.64
user 1302.43
sys 26.20
Les concatnations entre String sont plus claires que les oprations sur
StringBuffer, donc :
Prfrer les StringBuffer si de nombreuses modifications doivent tre
apportes une chane (par exemple dans une boucle).
Prfrer les String pour des affections simples de chanes
(le compilateur fera la transformation en StringBuffer pour vous !).
Voir aussi StringBuilder et http://java.sun.com/developer/
technicalArticles/Interviews/community/kabutz_qa.html
&
X. Crgut
141
'
&
X. Crgut
142
'
Les constructeurs :
public Integer(int);
public Integer(String);
&
X. Crgut
143
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// int i1 = n1;
// Erreur : types diffrents !
int i1 = n1.intValue();
double d2 = n2.doubleValue();
// d2 == 100.0
int i3 = Integer.parseInt("421");
Integer n4 = Integer.decode("0xFFF");
// i3 == 421
// n4 == 4095
boolean test;
// test = n1 == i1;
// test = i1 == n1;
// Types incompatibles
// Types incompatibles
// true
// false
&
X. Crgut
144
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int i1 = n1;
// en fait : i1 = n1.intValue()
double d2 = n2.doubleValue();
// d2 == 100.0
int i3 = Integer.parseInt("421");
Integer n4 = Integer.decode("0xFFF");
boolean test;
test = n1 == i1;
test = i1 == n1;
// i3 == 421
// n4 == 4095
// true
// true
// true
// false
&
X. Crgut
145
'
Les numrations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class ExempleEnum {
static Couleur getCouleur(Fruit f) {
Couleur resultat = null;
switch (f) {
case POMME: resultat = Couleur.JAUNE; break;
case ORANGE: resultat = Couleur.ORANGE; break;
case PRUNE: resultat = Couleur.VIOLET; break;
}
return resultat;
}
public static void main(String[] args) {
for (Fruit f : Fruit.values()) {
System.out.println(f + " est " + getCouleur(f));
}
}
}
&
X. Crgut
146
'
On peut ajouter des mthodes et des attributs dans une classe numre.
&
X. Crgut
147
'
X. Crgut
148
'
verbe
rle de B
rle de A
partie
&
X. Crgut
tout
partie
149
'
travaillepour 0..1
Personne
Entreprise
employ
1..*
Train
employeur
Wagon
1..*
Sige
{ordered}
0..1
passager *
0..1
conducteur
Personne
&
X. Crgut
150
'
Traduction en Java
0..1
conducteur
0..1
*
passager
Train
Personne
X. Crgut
151
'
Interfaces
&
X. Crgut
152
'
X. Crgut
153
'
Constatations
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)
&
X. Crgut
ListeChane
+taille: int
+item(indice: int): double
+remplacer(indice: int, x: double)
+ajouter(indice: int, x: double)
+supprimer(indice: int)
+constructor ListeChane()
suivante 0..1
Cellule
premire
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
&
X. Crgut
156
'
Dfinition : Une interface est le point de jonction entre des classes utilisant
linterface et des classes la ralisant.
Exemple : Linterface Liste est le point de jonction entre OutilsListe (en
fait, OutilsListe.somme) et ListeTab ou ListeChane.
Essentiel : Une interface dfinit un comportement qui doit tre respect par
ses ralisations et sur lequel peuvent sappuyer ses utilisateurs.
Consquence : La documentation est essentielle ! La signature des
mthodes ne suffit pas : utilisateurs et implmenteurs ne doivent pas pouvoir
avoir des interprtations incompatibles (ou contradictoires).
Intrt : Une interface dfinit un contrat entre utilisateurs et ralisateurs :
les implmenteurs doivent le respecter ;
les utilisateurs savent comment utiliser une interface.
&
X. Crgut
157
'
&
X. Crgut
158
'
X. Crgut
159
'
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
160
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&
X. Crgut
Exemple de ralisation
161
'
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
&
X. Crgut
162
'
&
X. Crgut
163
'
{ return this.elements[0]; }
{ return this.elements[this.nb - 1]; }
{ ... }
Les mthodes premier, dernier et trier sont disponibles dans ListeTab mais
pas dans Liste ni ListeChane.
Remarque : Ces mthodes pourraient tre dfinies sur ListeChane mais
avec un cot non constant pour dernier et trier.
&
X. Crgut
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
&
X. Crgut
165
'
&
X. Crgut
166
'
//
//
//
//
//
???
???
???
???
???
l1.dernier();
l2.dernier();
lt1.dernier();
lt.dernier()
//
//
//
//
???
???
???
???
&
X. Crgut
167
'
Liste l;
l = new ListeTab(9);
l.ajouter(0, 3.14);
168
'
Affectation renverse
Liste l;
// Dclaration de la poigne l de type liste
l = new ListeTab(9); // Crer une ListeTab et lattacher l
l.ajouter(0, 3.14);
// Appel de la mthode ajouter(int, double) sur l
ListeTab lt;
lt = l;
// Interdit par le compilateur mais ncessaire pour...
lt.trier();
// Trier la liste (opration non disponible sur Liste)
est refuse car Liste nest pas sous-type de ListeTab (mme si lobjet
associ l est bien du type ListeTab) : cest laffectation renverse.
lt = l
&
X. Crgut
if (l instanceof ListeTab) {
ListeTab lt = (ListeTab) l;
lt.trier();
}
Programmation objet en Java
169
'
170
'
X. Crgut
171
'
&
X. Crgut
172
'
&
X. Crgut
173
'
&
X. Crgut
174
'
&
X. Crgut
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
176
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
&
X. Crgut
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
178
'
Gnricit
&
X. Crgut
179
'
&
X. Crgut
180
'
Solutions
Principe : On constate que seul le type des lments de la liste change.
Les algorithmes (donc le code des mthodes) restent identiques.
Solution 1 (mauvaise) : Faire du copier/coller. Il faut :
Renommer tous les fichiers (Liste.java, ListeTab.java...) en prenant un
nouveau nom (ListeDouble, ListeTabDouble, ListeFraction... par exemple).
Remplacer le type double par le nouveau type.
Inconvnients : Mme si ces transformations peuvent tre automatises
elles sont fastidieuses !
Solution 2 (mauvaise) : Celle utilise avant java 1.5. Voir T. 241.
Solution 3 (la bonne) : Utiliser la gnricit ( partir de java 1.5 !)
&
X. Crgut
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
&
X. Crgut
182
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Le programme de test
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
183
'
Explications
Une classe gnrique est une classe paramtre par un (ou plusieurs) types.
public interface Liste<T> { ... }
public class Couple<A, B> { ... }
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
}
import java.awt.Color;
public class TesterCoupleErreur {
public static void main(String[] args) {
Couple<String, Integer> p1 = new Couple<String, Integer>("I", 1);
Couple<Integer, String> p2 = new Couple<Integer, String>(2, "II");
p1.premier = p2.second;
p1.second = p2.premier;
Couple<Color, String> p3 =
new Couple<Color, String> (Color.RED, "rouge");
p3.premier = "VERT";
p3.second = Color.GREEN;
&
X. Crgut
185
'
&
X. Crgut
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
&
X. Crgut
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
&
X. Crgut
188
'
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
}
public void ajouter(int index, T x) {
if (index == 0) {
// insertion en tte
this.premiere = new Cellule<T>(x, this.premiere);
} else {
// insertion aprs une cellule
Cellule<T> precedente = cellule(index-1);
Cellule<T> nouvelle = new Cellule<T>(x,
precedente.getSuivante());
precedente.setSuivante(nouvelle);
}
this.nb++;
// une cellule ajoute
}
&
X. Crgut
this.cellule(index).setElement(x);
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
190
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&
X. Crgut
Mthodes gnriques
191
'
&
X. Crgut
192
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&
X. Crgut
193
'
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
194
'
Relation dhritage
&
X. Crgut
195
'
Exemple introductif
&
X. Crgut
196
'
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
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
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
&
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; }
199
'
X. Crgut
200
'
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)
&
X. Crgut
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
{ return this.pt.getX(); }
{ return this.pt.getY(); }
{ return this.nom; }
&
X. Crgut
{ this.pt.afficher(); }
202
'
X. Crgut
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)
&
X. Crgut
204
'
X. Crgut
205
'
Hritage
206
'
Notation et vocabulaire
Notation UML
classe parente
classe de base
super classe
Point
PointNomm
classe fille
classe drive
sousclasse
Notation en Java
public class PointNomm
extends Point
{ ... }
// relation dhritage
207
'
/** 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;
}
}
X. Crgut
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) { ... }
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;
}
&
X. Crgut
210
'
211
'
&
X. Crgut
212
'
Redfinition de mthode
La classe drive peut donner une nouvelle version (nouveau corps) une
mthode dfinie dans la super-classe (adaptation du comportement).
Exemple : Dans la classe PointNomm, on peut (on doit !) redfinir
afficher pour que le nom du point apparaisse galement.
/** Afficher le point nomm sous la forme nom:(point) */
public void afficher() {
System.out.print(getNom() + ":");
super.afficher();
// utilisation du afficher de Point
}
// A:(0,4)
mthode de PointNomm !
213
'
Lannotation @Override
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) {}
}
X. Crgut
214
'
1
2
3
4
5
6
7
X. Crgut
215
'
Principe de substitution
216
'
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
X. Crgut
217
'
//
//
type
apparent
Point
PN
type
rel
null
Point
PN
null
Point
PN
218
'
&
X. Crgut
if (p instanceof PointNomme) {
PointNomme q = (PointNomme) p;
q.nommer("B");
}
219
'
X. Crgut
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
221
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+
+
+
+
+
+
+
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
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
223
'
La classe Object
&
X. Crgut
224
'
&
X. Crgut
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);
&
X. Crgut
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
{ return this.couleur; }
{ this.couleur = c; }
&
X. Crgut
*/
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)
228
'
X. Crgut
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
230
'
231
'
Hritage multiple
Dfinition : On dit quil a hritage multiple si une classe hrite dau moins
deux classes (parentes).
VHICULE
MAISON
AVION
BATEAU
MOBILEHOME
HYDRAVION
hritage multiple
hritage rpt
X. Crgut
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
233
'
Interfaces et hritage
&
X. Crgut
234
'
Attention : La liaison tardive fait que a < b b > a peut tre faux.
&
X. Crgut
235
'
X. Crgut
236
'
X. Crgut
237
'
238
'
Rutilisation
// A spcialise B
239
'
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
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
241
'
X. Crgut
242
'
243
'
&
X. Crgut
244
'
245
'
&
X. Crgut
246
'
public G getSommet() {
return lments[nb-1];
}
247
'
class TestPileFixe {
public static void main (String args []) {
PileFixe<Point> pile = new PileFixe<Point>(10);
// instanciation du paramtre gnrique
for (int i = 0; i < 10; i++) {
pile.empiler(new Point(i, i));
}
while (!pile.estVide()) {
pile.getSommet().afficher();
pile.dpiler();
}
}
}
&
X. Crgut
248
'
&
X. Crgut
249
'
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
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
&
X. Crgut
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
253
'
1
2
3
4
5
6
7
8
9
10
Gnricit et sous-typage
254
'
255
'
Cette solution est meilleure car T ntait jamais utilis (ne servait rien).
Rq : On peut utiliser des types joker contraints (<?
&
X. Crgut
extends Type>).
256
'
Exercice 36 crire une mthode de classe qui copie une liste dans une
autre.
&
X. Crgut
257
'
Tableau et sous-typage
&
X. Crgut
258
'
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
259
'
Premire solution ?
public static <T> void copier(Liste<T> destination, Liste<T> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}
Et non !
&
X. Crgut
260
'
Solution : Dire quil y a une relation de sous-typage entre les deux types
public static <T1, T2 extends T1>
void copier(Liste<T1> destination, Liste<T2> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}
Contrainte sur T2
Solution plus gnrale :
public static <T>
void copier(Liste<? super T> destination, Liste<? extend T> source) {
for (int i = 0; i < source.taille(); i++) {
destination.ajouter(destination.taille(), source.item(i));
}
}
X. Crgut
261
'
&
X. Crgut
262
'
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() { ... }
...
}
{ ... }
&
X. Crgut
263
'
&
X. Crgut
264
'
X. Crgut
265
'
{
{
{
{
{
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
266
'
Programmation dfensive
&
X. Crgut
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
268
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.*;
// io pour input/output
public class Moyenne {
/** Afficher la moyenne des valeurs relles du fichier args[0] */
public static void main (String args []) {
try {
BufferedReader in = new BufferedReader(new FileReader(args[0]));
int nb = 0;
// nb de valeurs lues
double somme = 0; // somme des valeurs lues
String ligne;
// une ligne du fichier
while ((ligne = in.readLine()) != null) {
somme += Double.parseDouble(ligne);
nb++;
}
in.close();
System.out.println("Moyenne = " + (somme / nb));
} catch (IOException e) {
System.out.println("Problme dE/S : " + e);
e.printStackTrace();
} catch (NumberFormatException e) {
System.out.println("Une donne non numrique : " + e);
}
}
}
&
X. Crgut
269
'
&
X. Crgut
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
271
'
Exceptions : Principe
&
X. Crgut
272
'
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
&
X. Crgut
273
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
&
shell returned 1
X. Crgut
274
'
Error
VirtualMachineError
OutOfMemoryError
IOException
IndexOutOfBoundsException
FileNotFoundException
&
X. Crgut
RuntimeException
ArtithmeticException
IllegalArgumentException
NumberFormatException
275
'
X. Crgut
276
'
La classe java.lang.Throwable
Throwable(String message)
cause de lexception ;
Throwable() : constructeur par dfaut (message == null) ;
Throwable(Throwable cause) : constructeur avec cause ;
Throwable(String message, Throwable cause) ;
printStackTrace() : afficher la trace des appels de mthodes ;
getMessage() : le message pass en paramtre du constructeur ;
getCause() : la cause de lexception ;
...
Exception
277
'
java.lang.AssertionError
java.lang.LinkageError
+-- java.lang.ClassCircularityError
+-- java.lang.ClassFormatError
+-- java.lang.UnsupportedClassVersionError
+-- java.lang.ExceptionInInitializerError
+-- java.lang.IncompatibleClassChangeError
+-- java.lang.AbstractMethodError
+-- java.lang.IllegalAccessError
+-- java.lang.InstantiationError
+-- java.lang.NoSuchFieldError
+-- java.lang.NoSuchMethodError
+-- java.lang.NoClassDefFoundError
+-- java.lang.UnsatisfiedLinkError
+-- java.lang.VerifyError
java.lang.ThreadDeath
java.lang.VirtualMachineError
+-- java.lang.InternalError
+-- java.lang.OutOfMemoryError
+-- java.lang.StackOverflowError
+-- java.lang.UnknownError
&
X. Crgut
278
'
&
X. Crgut
279
'
&
X. Crgut
280
'
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>);
}
&
X. Crgut
281
'
Le bloc try
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 ?
}
&
X. Crgut
282
'
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)
}
283
'
X. Crgut
284
'
285
'
Ltiquette javadoc @throws signale que la mthode peut lever une exception.
Justification : Lappelant de la mthode connait ainsi les exceptions potentielles
exception = paramtre en sortie... gnralement non disponible.
Exemple : Spcification de la mthode java.util.Collection.remove(Object)
/**
* Removes a single instance of the specified element from this
* collection, if it is present (optional operation). More formally,
* removes an element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>, if
* this collection contains one or more such elements. Returns
* <tt>true</tt> if this collection contained the specified element (or
* equivalently, if this collection changed as a result of the call).
*
* @param o element to be removed from this collection, if present
* @return <tt>true</tt> if an element was removed as a result of this call
* @throws ClassCastException if the type of the specified element
is incompatible with this collection (optional)
*
* @throws NullPointerException if the specified element is null and this
collection does not permit null elements (optional)
*
* @throws UnsupportedOperationException if the <tt>remove</tt> operation
is not supported by this collection
*
*/
boolean remove(Object o);
&
X. Crgut
286
'
287
'
import java.io.FileReader;
class A {
void m1() {
FileReader f = new FileReader("info.txt");
}
}
Rsultat de la compilation
ExceptionSpecificationReader.java:5: unreported exception
java.io.FileNotFoundException; must be caught or declared to be
thrown
FileReader f = new FileReader("info.txt");
^
1 error
&
X. Crgut
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
289
'
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 { };
&
X. Crgut
290
'
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
291
'
&
X. Crgut
292
'
&
X. Crgut
293
'
X. Crgut
294
'
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
295
'
&
X. Crgut
296
'
Lexception FormatEntierException
&
}
X. Crgut
297
'
&
X. Crgut
298
'
&
X. Crgut
299
'
bnfices
client
fournisseur
X. Crgut
300
'
&
X. Crgut
301
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// x positif
// la racine carre est positive
// son carr est x
302
'
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
303
'
X. Crgut
304
'
&
X. Crgut
//
//
//
//
-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
'
// prendre lun
// ou lautre
&
X. Crgut
306
'
307
'
// fraction unit
&
X. Crgut
308
'
&
X. Crgut
{ ... }
309
'
/** Changer
//@ ensures
//@ ensures
public void
le signe de la fraction. */
getNumerateur() == - \old(getNumerateur());
getDenominateur() == \old(getDenominateur());
opposer()
{ num = - num; }
&
X. Crgut
310
'
&
X. Crgut
311
'
&
X. Crgut
312
'
X. Crgut
313
'
&
X. Crgut
314
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
&
X. Crgut
315
'
Par dfaut, les assertions ne sont pas vrifies. Elles sont actives avec
loption -ea et dsactives avec -da au niveau de la classe ou du paquetage
(-esa et -dsa pour les classes systme).
licorne> java -ea RacineCarree # toutes les classes sauf systme
Donnez un rel : 4
RC(4.0) = 2.0
RC(0) = 0.0
...
RC(81) = 9.0
Exception in thread "main" java.lang.AssertionError: x ngatif -4.0
at RacineCarree.RC(RC_assert.java:4)
at RacineCarree.main(RC_assert.java:20)
&
X. Crgut
316
'
&
X. Crgut
317
'
Classes internes...
&
X. Crgut
318
'
319
'
Solution
X. Crgut
320
'
1
2
3
4
5
&
X. Crgut
321
'
OutilsListe
interface
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
322
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
&
X. Crgut
323
'
Discussion
2.
ListeTab
ListeTab
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
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
&
X. Crgut
325
'
X. Crgut
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
&
X. Crgut
327
'
Classe interne
Dfinition : Une classe interne est une classe dfinie lintrieur dune
autre classe.
Avantages : La classe interne est dans lespace de nom de lautre classe et a
donc accs toutes ses informations (y compris celles dclares private).
Classe interne membre : (T. 327) Elle contient un accs sur lobjet qui a
permis sa cration (et rcupre les paramtres de gnricit).
Liste<Double> ll = ...;
Iterateur<Double> it = ll.iterateur();
// it est construit partir de ll
ListeTab<Double> lt = ...;
Iterateur<Double> it2 = lt.new IterateurTab();
Classe interne statique : (T. 325) Elle nest associe aucun objet de la
classe englobante.
&
X. Crgut
328
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Classe anonyme
// lment parcourir
};
public T suivant() {
return elements[this.curseur++];
}
// Ne pas oublier le point-virgule
}
}
Une classe anonyme est une classe qui na quune seule instance.
Peut avoir accs aux variables locales du sous-programme condition
quelles soient dclares final ;
&
X. Crgut
329
'
&
X. Crgut
330
'
Les collections
X. Crgut
331
'
&
X. Crgut
332
'
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
333
'
Principales collections
X. Crgut
334
'
Linterface java.util.Collection
335
'
Linterface java.util.Collection<E>
&
X. Crgut
336
'
Linterface java.util.List<E>
Structure de donnes o chaque lment peut tre identifi par sa position.
boolean add(E e)
// ajouter e la fin de la liste
void add(int i, E e)
// ajouter e lindex i
E set(int i, E o)
boolean addAll(int, Collection<? extend E> c)
// ... insrs partir de i
E get(int i)
// lment lindex i
int indexOf(Object o)
// index de lobjet o dans la liste ou -1
int lastIndexOf(Object o)
// dernier index de o dans la liste
List<E> subList(int from, int to)
// liste des lments [from..to[
E remove(int i)
ListIterator<E> listIterator()
ListIterator<E> listIterator(int i)
&
X. Crgut
337
'
La classe java.util.Vector<E>
E get(int index)
E elementAt(int index)
// vecteur[index]
// get(index)
boolean add(E o)
&
X. Crgut
338
'
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
Object[] toArray()
339
'
Queue
retourne une
valeur spcifique
ajouter
add(E)
offer(E)
false
supprimer
remove
poll
null
examiner
element
peek
null
&
X. Crgut
340
'
boolean containsKey(Object k)
// k est-elle une cl utilise ?
boolean containsValue(Object v) // v est-elle une valeur de la table ?
Set<Map.Entry<K, V>> entySet()
Set<K>
keySet()
Collection<V>
values()
&
X. Crgut
341
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Map;
import java.util.HashMap;
public class CompteNbOccurrences {
/** Compter le nombre doccurrences des chanes de args... */
public static void main(String[] args) {
Map<String, Integer> occ = new HashMap<String, Integer>();
for (String s : args) {
if (occ.containsKey(s)) {
occ.put(s, 1 + occ.get(s));
} else {
occ.put(s, 1);
}
}
System.out.println("occ = " + occ);
System.out.println("cls = " + occ.keySet());
System.out.println("valeurs = " + occ.values());
System.out.println("entres = " + occ.entrySet());
// afficher chaque entre
for (Map.Entry<String, Integer> e : occ.entrySet()) {
System.out.println(e.getKey() + " --> " + e.getValue());
}
&
X. Crgut
342
'
CompteNbOccurrences A B C A C D E A A D E
est :
&
X. Crgut
343
'
&
X. Crgut
344
'
Linterface java.util.Iterator<E>
Objectif : Un itrateur est un objet qui permet de parcourir tous les
lments dune collection.
boolean hasNext() // reste-t-il des lments dans la collection ?
E next()
// llment suivant (et avancer)
void remove()
// supprimer llment (peut ne pas tre dfinie)
Exemple dutilisation :
Collection<Double> c = ...
Iterator<Double> it = c.iterator();
while (it.hasNext()) {
Double lment = it.next(); // retourne llment courant et avance
// manipuler lment...
}
X. Crgut
345
'
Linterface java.util.Iterable<E>
Intrt : Il est possible dutiliser foreach sur toute classe qui ralise
Iterable.
Iterable<E> collection = ...
for (E o : collection) {
faire(o);
}
&
X. Crgut
346
'
X. Crgut
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
348
'
X. Crgut
349
'
&
X. Crgut
Entre
Reader
InputStream
Sortie
Writer
OutputStream
350
'
La classe InputStream
&
X. Crgut
351
'
La classe OutputStream
&
X. Crgut
352
'
&
X. Crgut
353
'
Concrtisations de InputStream
InputStream
SequenceInputStream
ByteArrayInputStream
FileInputStream
ObjectInputStream
PipedInputStream
StringBufferInputStream
354
'
Concrtisations de OutputStream
OutputStream
ByteArrayOutputStream
FileOutputStream
ObjectOutputStream
PipedOutputStream
355
'
&
X. Crgut
356
'
&
X. Crgut
357
'
&
X. Crgut
358
'
La classe java.io.File
&
X. Crgut
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)
&
X. Crgut
360
'
&
X. Crgut
361
'
import java.io.File;
public class Lister {
public static void lister(File file) {
System.out.print(file.getName());
if (!file.exists()) {
System.out.println(": fichier ou rpertoire inexistant !");
} else if (file.isDirectory()) {
System.out.println(":");
lister(file, file.list());
System.out.println();
}
else {
if (file.canExecute()) {
System.out.print("*");
}
System.out.println();
}
}
&
X. Crgut
362
'
20
21
22
23
24
25
26
27
28
29
30
&
X. Crgut
363
'
InputStream
...
ByteArrayInputStream
FilterInputStream
FileInputStream
BufferedInputStream
...
InflaterInputStream
DataInputStream
PushbackInputStream
&
X. Crgut
364
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.*;
public class FlipCaseInputStream extends FilterInputStream {
public FlipCaseInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int c = super.read();
// idem in.read()
int newC = c;
if (Character.isUpperCase(c)) {
newC = Character.toLowerCase(c);
} else if (Character.isLowerCase(c)) {
newC = Character.toUpperCase(c);
}
return newC;
}
}
&
X. Crgut
Dfinir un FilterInputStream
365
'
import java.io.*;
public class TestFlipCaseInputStream {
public static void afficher(InputStream in) throws IOException {
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
}
public static void main(String[] args) throws IOException {
InputStream inStream = new FlipCaseInputStream(
new FileInputStream(args[0]));
afficher(inStream);
inStream.close();
}
}
&
X. Crgut
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
367
'
import java.io.*;
public class TestFiltres {
public static void main(String[] args) throws IOException {
DataOutputStream dos =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("/tmp/fichier.out")));
dos.writeDouble(12.5);
dos.writeUTF("Dupond");
dos.writeInt(421);
dos.close();
}
}
&
X. Crgut
368
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.*;
import java.util.zip.GZIPOutputStream;
public class GZipper {
public static void zipper(String nom) throws IOException {
String nomSortie = nom + ".gz";
GZIPOutputStream sortie = new GZIPOutputStream(
new FileOutputStream(nomSortie));
InputStream entree = new FileInputStream(nom);
int c;
while ((c = entree.read()) != -1) {
sortie.write(c);
}
entree.close();
sortie.close();
}
&
X. Crgut
369
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.*;
import java.util.zip.*;
public class Zipper {
public static void zipper(String nomArchive, String[] noms)
throws IOException {
ZipOutputStream sortie = new ZipOutputStream(
new FileOutputStream(nomArchive));
for (String nom: noms) {
// ajouter une entre
sortie.putNextEntry(new ZipEntry(nom));
InputStream entree = new FileInputStream(nom);
int c;
while ((c = entree.read()) != -1) {
sortie.write(c);
}
entree.close();
sortie.closeEntry();
}
sortie.close();
}
&
X. Crgut
370
'
import java.io.*;
import java.util.zip.*;
public class Dezipper {
public static void main(String[] args) throws IOException {
ZipInputStream zin = new ZipInputStream(
new FileInputStream(args[0]));
ZipEntry entree = zin.getNextEntry();
while (entree != null) {
String nomEntree = "/tmp/" + entree.getName();
FileOutputStream out = new FileOutputStream(nomEntree);
Copier.copier(out, zin);
out.close();
zin.closeEntry();
entree = zin.getNextEntry();
}
zin.close();
}
}
&
X. Crgut
371
'
&
X. Crgut
372
'
Complments
&
X. Crgut
373
'
La classe Object
X. Crgut
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.
&
X. Crgut
375
'
&
X. Crgut
376
'
// car composition
&
X. Crgut
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
378
'
(CLASSE)
&
X. Crgut
379
'
X. Crgut
380
'
X. Crgut
381
'
382
'
X. Crgut
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
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
384