Initiation à la Programmation Orientée Objets en · PDF fileOrientée...
Transcript of Initiation à la Programmation Orientée Objets en · PDF fileOrientée...
Eric Anquetil ([email protected])Dépt. InformatiqueInsa Rennes
Initiation à la Programmation g
Orientée Objets en JavaVersion 1.3
Module de Pre-Spécialisation
Eric Anquetil ([email protected]) 07/01/2010
Init POO en Java / Version 1.3
1
Initiation à la Programmation Orientée Objets en Java
Version 1.3Module de Pre-Spécialisation
►PréambuleUne définition de la programmationLangage et Programmation
►Introduction sur Java Portabilité de JavaJava et InternetJava Virtuelle Machine (JVM) / sécuritéProgrammes Java de 2 typesPlate-forme de développement (JDK )Bibliothèques JavaEnvironnement intégré de développement : IDE
► Introduction à la programmation orientée objetIntroduction à la programmation orientée objetNotion d’objetNotion de classe : abstraction1er diagramme de classes UMLNotion d’agrégationNotion d’héritageNotion d’héritage et de Polymorphisme
► Les objets et les classes en JavaLes objets JavaLes types primitifsExemple : la classe PointInvocation des méthodes et attributs / thisSurcharge de méthodesParamètres des méthodesParamètres des méthodes (bis)Encapsulation et contrôle d’accèsDéfinition d’une classe : résumé
► Unité de compilationUnités de compilation FichierExemple d’unité de compilation / main
1
2
34
5
6789
101112
13
14151617181920
21
222324252627282930
31
3233
Eric Anquetil ([email protected]) 07/01/2010
Init POO en Java / Version 1.3
2
► PackagesUtilisation des Packages : espace de nommageDéfinition de Package - contrôle d’accès
► Égalité d'objets (1ère approche)Égalité d'objets (surcharge)
► Membre statiqueMembres statiques : static
► Donnée constanteDonnées constantes : final
► L’agrégationAgrégation : classe Point / RectangleAgrégation : exemple de la classe Rectangle
► Notion de recopieRéférence : copie superficielleRéférence : notion de copie en profondeur
►Exercice Conception d’une classe PolygoneDéfinition de la classe PolygoneDiagramme de classes : Point / PolygonePolygone : 1ère versionPolygone : translation d'un polygone ferméPolygone : problème de référencePolygone : notion de recopieNouveau diagramme de classes : Point / Polygone
► Gestion mémoireDurée de vie des objetsLe ramasse miette ou « garbage collector »La méthode finalize()
► HéritageIntroductionHéritage : diagramme de classe (Personne /employe)Héritage : la classe PersonneHéritage : constructeur / extendsHéritage : des attributs et des méthodes Héritage : enrichissement d'une méthode Héritage : redéfinition d'une méthode Héritage : redéfinition et attachement dynamiqueHéritage : exemple d'exploitation de l’attachement dynamique
34
3536
37
38
39
40
41
42
43
4445
46
4748
49
50515253545556
57
585960
61
626364656667686970
Eric Anquetil ([email protected]) 07/01/2010
Init POO en Java / Version 1.3
3
gHéritage : accès aux membres propres de l'objet dérivéHéritage : instanceof
► Contrôles d’accèsSynthèse des différents contrôles d’accès en Java
► La classe ObjectDéfinition de java.lang.Object
► Égalité d'objets (surcharge /redéfinition)Égalité d'objets (surcharge de equals)Égalité d'objets (redéfinition de equals)
► Classe abstraiteClasse et méthode abstraites : abstractExemple de Classe et méthode abstraites
► InterfaceInterface Java : implementsExemple d'utilisation d'interface 1/2Exemple d'utilisation d'interface 2/2Interface : Diagramme de ClassesInterface et héritageInterface Versus Classe abstraite
► Collection JavaLes collections Java : PrincipeLes collections Java : Vector, List, …Collection Java : l'interface collectionCollection Java : les interfacesCollection Java : interfaces / classes abstraitesCollection Java : diagramme de classes du frameworkCollection Java : les iterateursCollection Java : un petit exemple
► ExceptionNotion d'erreur / ExceptionTraitement des cas d'erreurs exceptionnellesExemple : mécanisme d'exception / finallyRéception / traitement d'une exceptionLancement d'exceptions / throwCapture et traitement d'exceptions / try … catchRetransmission d’une exceptionException standard en JavaCréer vos propres classes d'exceptions : ThrowableCréer vos propres classes d'exceptions : MonExceptionExemple complet
7172
73
74
75
76
77
7879
80
8182
83
848586878889
90
9192939495969798
99
100101102103104105106107108109110
Eric Anquetil ([email protected]) 07/01/2010
Init POO en Java / Version 1.3
4
► Clonage et copie en profondeurNotion de copie en profondeurLa méthode clone( ) de la classe ObjectMise en œuvre de la méthode clone()Mise en œuvre de la méthode clone()Clonage et héritageRemarques sur le clonage en Java
► Classe interne Classe interne : inner classClasse interne : membre d'une classeClasse interne : localeClasse interne : anonymeClasse interne : anonyme
► AWT2 mots sur l’AWT et JFCHiérarchie de composants et conteneursExemple 1 : une JFrameExemple 2 : Jframe / JLabelExemple 3 : Jframe / JPanelExemple 4 : Jframe / MenuBarPrincipe de la gestion des événements (JDK 1.1 et +)
Évènements et Interfaces "Listener"Les interfaces "Listener"Exemple 5 : Évènements et JFrameUtilisation d'un "Listener Adapter"Exemple 6 : Jframe / JbuttonObjets Sources et Objets délégués
► Exemple : une application graphique basée sur 2 Jpanel(introduction au TP)Présentation de L’IHMPréambule : les figures géométriques de baseLes figures géométriques de base / EllipseL’Architecture : 1 premier diagramme de ClasseLe Panel des Icones / ConstructeurLe Panel des Icones / PaintLe Panel des Icones / Gestion des évènementsIHM : ce qu’il reste à faireL’Architecture : diagramme de Classe avec gestion des evts
► Introduction aux Applets
111
112113114115116117
118
119120121122123
124
125126127128129130131132133134135136137
138
139140141142143144145146147
148
Eric Anquetil ([email protected]) 07/01/2010
Init POO en Java / Version 1.3
5
« Applet » : utilisation d’un framework simple« Applet » : chargement d'une Applet« Applet » : démonstration« Applet » : un exemple / code« Applet » : invocation de l'Applet / html« Applet » : action du paint
► Introduction aux GenericsLes Generics – IntroductionLes Generics – Définition de “generics”Les Generics – Définition de “generics”Les Generics – HéritageLes Generics – Wildcards et Bounded WildcardsLes méthodes Generic
► Quelques remarquesQuelques Remarques 1/2 ....Quelques Remarques 2/2....
► Annexes► Java 5 Tiger les petits plusIntroduction : Java5 (Tiger)Autoboxing et Auto-Unboxing des types primitifsItérations sur des collections : nouvelle boucle forType énuméré : enumNombre d’arguments variable pour une méthodePrintf : Sortie standard formatéeLe scanner : entrée formatée Les imports statiques
149150151152153154
155
156157158159160161
162
163164
165
166
167168169170171172173174
Eric Anquetil ([email protected])Dépt. InformatiqueInsa Rennes
Initiation à la Programmation g
Orientée Objets en Java
Version 1.3Module de Pre-Spécialisation
P é b l►Préambule
Une définition de la programmation
Premier aspect : la notion de programmation dite « impérative » Premier aspect : la notion de programmation dite « impérative »>> succession d’instructions qui produisent le résultat souhaité
Notion de calcul / illustration : une recette
1. Mettre 300g de farine
2. De la levure de boulanger
3 Verser l’eau jusqu’à obtenir une pâte homogène
Faire la pâte
3. Verser l eau jusqu à obtenir une pâte homogène
4. Etc.
S d t i ti é ti t di ti d l i Second aspect : organisation, coopération et coordination de plusieurs entités
Notion d’interaction / illustration : un restaurant :
Ensemble de personnes (entités) qui ont des tâches à réaliser (séquences d’instructions) en interaction mutuelle avec leur milieu extérieur (communication).
@iri
sa.f
r
(communication).
Ces 2 aspects sont omniprésents en programmation : base de
eric
.anq
uetil
@
3
données, interface homme-Machine, réseau Internet, …
Langage et Programmation
Langage de programmation : Langage de programmation : Définition d’une syntaxe précise, de structures de contrôle, structures de
données, de séquences d’instructions prédéfinies (« haut niveau »), etc.
Langage et paradigme de programmation Un langage est "souvent" associé à un paradigme de programmation,
cad à une approche pour définir, organiser, utiliser la connaissance. pp p , g ,
Programmation fonctionnelle : scheme, camel, …
Centrée sur une décomposition en fonctions qui rendent des résultats
Programmation impérative : Pascal C Programmation impérative : Pascal, C, …
Centrée sur une structuration « séquentielle » des traitements
Programmation objet : C++, Java, Eiffel, …
C t é l d é / ié à l t it t é ifi Centrée sur les données / associées à leurs traitements spécifiques
Apprendre un langage et savoir programmer
@iri
sa.f
r
Apprendre un langage et savoir programmer ce n’est pas seulement apprendre une syntaxe et des mots clés,
c’est surtout apprendre à aborder et résoudre un problème par rapport au paradigme sous tendu par le langage
eric
.anq
uetil
@
4
paradigme sous tendu par le langage
►Introduction sur ►Introduction sur Java
Portabilité de Java
Java est indépendant du matériel (portable) Java est indépendant du matériel (portable)
le même programme peut s’exécuter sur n’importe quelle plate-forme (PC, Mac, Linux…)
Principe de la portabilité : Java est interprété
Le compilateur Java (javac) produit du pseudo-code (byte code) indépendant de la plate-forme et interprétable (java) par une machine virtuelle : la Java p p (j ) pVirtual Machine (JVM)
Chaque plate-forme possède sa propre machine virtuelle
Interprétation sur JVM
Windows NTProgramme en langage
Java Compilateur
JavaProg
ByteCode
Windows NT
Interprétation sur JVM
@iri
sa.f
r
= source
Interprétation sur JVM
…
eric
.anq
uetil
@
6
sur JVM Mac OS
Fichier .java Javac Fichier .Class Java
Java et Internet
Java et Internet Java et Internet
Objectif
Écrire un programme sur une machine, le transmettre sur le réseau et l’exécuter sur des machines totalement différentes, quelques soient leur système d’exploitation (Windows NT, Linux…).
Caractéristiques nécessaires
Robustesse
minimisation des risques de « crash » (beaucoup de vérifications faites minimisation des risques de « crash » (beaucoup de vérifications faites par le compilateur Java)
Portabilité
indépendance vis-à-vis du système d’exploitation (grâce à la JVM)
@iri
sa.f
r
Sécurité
pas de virus… (la JVM masque la machine)
eric
.anq
uetil
@
7
Java Virtuelle Machine (JVM) / sécurité
Chargement dynamique d l
Protection dynamique
Vérification des accès aux ressourcesdes classes
Copie en mémoire des classes demandéeslors de l'exécution du programme
Modulable selon le contexte d'exécution
(programme, Applet, Applet signées)
Fichiers
byte-code
class
Chargeur de classes
(Class Loader)
Gestionnaire de sécurité
(Security Manager).class
Vérificateur de byte-codes(Verifier)
Moteur d'exécution
(Interpreter)
@iri
sa.f
r
( )
Vérification statique
JVM: Java Virtuelle Machine
eric
.anq
uetil
@
8
Vérification statique du byte-code
Programmes Java de 2 types
Java permet de développer deux types de programmes Java permet de développer deux types de programmes selon leur contexte d'exécution
Les applications autonomes
Les Applets
Programmes Java destinés à fonctionner via un navigateur Web
Programmes chargés
@iri
sa.f
r
à travers une page HTML
eric
.anq
uetil
@
9
Plate-forme de développement (JDK )
Outils nécessaires pour développer des programmes Java Outils nécessaires pour développer des programmes Java
Un éditeur de texte (notepad, xemacs, …) pour écrire le programme
Un compilateur Java
Un interpréteur de byte code
Le JDK (Java Development Kit) est téléchargeable gratuitement il contient notamment :il contient notamment :
javac : compilateurs de sources java
fichier source .java ---> byte-code .class
java : interpréteur de byte code
fichier byte-code .class est interprété
jdb : débogueurjdb : débogueur
pour détecter les erreurs dans un programme
javadoc : génération de documentation en HTML
@iri
sa.f
r
Appletviewer : permet de tester une applet (sans passer par un browser Web)
Les API (Application Programming Interface)
un ensemble complet de modules prédéfinis pour le développement
eric
.anq
uetil
@
10
un ensemble complet de modules prédéfinis pour le développement d'applications en Java (graphisme 2D, 3D, communication Internet, …)
Bibliothèques Java
Java offre un ensemble complet de bibliothèques standardisées :p q
cf. pour une documentation détaillée : http://java.sun.com
java.lang : classes de base du langage (Class, Character, Math, Process, ...)
java.util : structures de données (Collections, HashMap, Vector, ...)
java.io : entrées - sorties classiques (File, InputStream, OutputStream, ...)
java.awt : interface Homme-Machine (Button, Canvas, Graphics2D, Image, ...)
java.net : communication internet (URL, Socket, ...)
java.applet : gestion des programmes destinés à fonctionner via
un browser Web ...
@iri
sa.f
r
D'autres bibliothèques
JGL (extension des structures de données), JFC (extension de l'AWT), ...
eric
.anq
uetil
@
11
Environnement intégré de développement : IDE
IDE : Environnement intégré de développement IDE : Environnement intégré de développement Objectif : faciliter au maximum le travail de développement
ex : Eclipse (Ibm), Jbuilder (Borland), Visual Café (symantec), …
Ils intègrent notamment sous un environnement commun :
un éditeurun éditeur
une interface pour compiler, exécuter, générer et visualiser la documentation…
d til d dé l t i l des outils de développement visuels pour :
la création d'interfaces graphiques
la détection d'erreurs, le parcours du code, …
des outils de gestion de projets, de travail en groupe
E emple L'EDI Eclipse
@iri
sa.f
r
Exemple : L'EDI Eclipse
Plate-forme modulaire (plug in) pour les développements informatiques
Java, UML, C++, etc.
eric
.anq
uetil
@
12
IBM en est à l'origine : aujourd'hui sous licence publique
cf. http://www.eclipse.org/
► Introduction à la ti programmation
orientée objetorientée objet
Introduction à la programmation orientée objet
La programmation orientée objet est axée La programmation orientée objet est axée
1/ sur les données / encapsulées autour d’un concept appelé : « objet »
2/ sur les traitements qui y sont associés.
la complexité des programmes est alors répartie sur chaque « objet ».
les langages objets (C++, smaltalk, java, ...) facilitent g g j ( , , j , )grandement cette approche de programmation.
L dèl bj t t tili bl i bi Le modèle objet est utilisable aussi bien pour
l’analyse, la conception, le codage.
cohérence pendant le développementp pp
facilite la réalisation de programme : développement et exploitation de gros logiciels
@iri
sa.f
r
Principes de base
abstraction, encapsulation, agrégation, héritage, polymorphisme
eric
.anq
uetil
@
14
Notion d’objet
Les objets / Encapsulation : Les objets / Encapsulation : Un objet est constitué :
d’une collection d’attributs (définissant l’état de l’objet)
t d éth d ié (défi i t t t) et de méthodes associées (définissant son comportement)
Modularité et masquage de l’informationg
les méthodes constituent l’interface de communication.
la manipulation d’un objet peut s’opérermaVoiture
la manipulation d un objet peut s opérer indépendamment de sa mise en œuvre (structure interne) ;
immatriculation = 432...
accelerer()
Attributs
Méth d
vitesse = O km/h
accelerer()ralentir()
Méthodes
@iri
sa.f
r
Les attributs sont « encapsulés » dans l’objet et par conséquent protégeables contre des accès non autorisés
Attributs
eric
.anq
uetil
@
15
contre des accès non autorisés
Notion de classe : abstractionVoiture
Les classes (abstraction de données) :
« Une classe est un prototype (moule) qui définit la nature des attributs et les méthodes
# immatriculation: String
# vitesse: String
+ accelerer()qui définit la nature des attributs et les méthodes communs à tous les objets d’un certain type. »
+ accelerer()
+ ralentir()
Un objet est l’instance d’une classe
Une classe permet par instanciation de construire des objets
exemples : e e p esv1 et v2 sont deux instances (objets) de la classe Voiture
v1
it 10 k
v2
it 50 k
@iri
sa.f
r
vitesse = 10 km
immatriculation = 432...
accelerer()
vitesse = 50 km
immatriculation = 124...
accelerer()
eric
.anq
uetil
@
16
ralentir() ... ralentir() ...
1er diagramme de classes UML
1er pas vers un diagramme de classes UML 1er pas vers un diagramme de classes UML
Notation
contrôle d’accès - : privé + : publique # : protégé
membre static : _
Classe
Att ib t # immatriculation: String
Voiture
Attributs # immatriculation: String
- moteur: Moteur
# vitesse: String
Méthodes
g
+ accelerer()
+ main()
@iri
sa.f
r
+ main()
+ ralentir()
eric
.anq
uetil
@
17
Notion d’agrégation
Association entre deux classes de type : ensemble / élément Association entre deux classes de type : ensemble / élément
Exploitation d’un concept pour définir un autre concept
Une voiture possède un moteur
MoteurVoiture- moteur
# puissance: int
+ démarrer()
# immatriculation: String
# vitesse: String
- moteur: Moteur
- moteur
0..1
+ accelerer()
+ ralentir()
public class Voiture {
protected String immatriculation;
@iri
sa.f
r
protected String vitesse;
private Moteur moteur;
public void accelerer() {System.out.println("accelererVoiture");};
bli id l ti () {S t t i tl (" l ti V it ") }
eric
.anq
uetil
@
18
public void ralentir() {System.out.println("ralentirVoiture");};
}
Notion d’héritage
Notion d’héritage Notion d héritage
« On peut raffiner la notion d’abstraction de données en utilisant la notion d ’héritage »
Une classe (classe dérivée) peut être spécialisée à partir d’une autre classe (classe de base)
Chaque sous classe (ou classe dérivée) hérite de toutes les caractéristiques de la classe de base (attributs et méthodes)
VoitureMoteur
classe de base (attributs et méthodes)
Cl# immatriculation: String
- moteur: Moteur
# vitesse: String
# puissance: int
+ démarrer()
Moteur - moteur
0..1 Une classe dérivée peut
ajouter des attributs et d éth d
Classede base
+ accelerer()
+ main()
+ ralentir()
Classes dérivées
des méthodes
@iri
sa.f
r
Formule1 VoitureElectrique
Classes dérivées
Une classe dérivée peut aussi redéfinir les
éth d d l l
eric
.anq
uetil
@
19
+ accelerer()
+ passerVitesse()
# tauxChargeBatterie: int
+ recharger()
méthodes de la classe de base.
Notion d’héritage et de Polymorphisme
Notion d’héritage et de Polymorphisme Notion d héritage et de Polymorphisme
Polymorphisme : mécanisme qui autorise l’appel d’une méthode qui à été redéfinie sur différents objets en provoquant des actions différentes selon la nature de l’objet.
public static void main(String [] args) {
Formule1 f1=new Formule1();
VoitureElectrique vElec=new VoitureElectrique();
# immatriculation: String
- moteur: Moteur
# vitesse: String
Voiture
# puissance: int
+ démarrer()
Moteur - moteur
0..1
Classede base
new VoitureElectrique();
Voiture[] tabVoit={f1,vElec};
for (int i=0; i< tabVoit.length; i++) {
g
+ accelerer()
+ main()
+ ralentir()
+ démarrer()
( ; g ; ) {
tabVoit[i].accelerer();
}
}Formule1 VoitureElectrique
Classes dérivées
@iri
sa.f
raccelererFormule1
accelererVoiture
+ accelerer()
+ passerVitesse()
Formule1
# tauxChargeBatterie: int
+ recharger()
VoitureElectrique
eric
.anq
uetil
@
20
► Les objets et les ► Les objets et les classes en Java
Les objets Java
Tout objet doit être créé « NEW »
Rappels
Tout objet doit être créé « NEW »
Tous les objets sont alloués « new » dans le Tas (mémoire dynamique)
Point p = new Point(10,10) ; // appel au constructeur de la classep ( , ) ; pp
L'identificateur d'un objet correspond à une "référence" sur l'objet
Point p1 ; // déclaration uniquement d’un identificateur ~pointeur
// - NULL si p1 est un champ d’une classe
// - non initialisé si c’est une variable locale
Point p2 = new Point( ) ; // java : créer explicitement un nouvel objet
p2 @
@iri
sa.f
rp1 = p2 ; // p1 et p2 correspondent à 2 identificateurs du même objet
// ~ "pointent ou référencent le même objet"
p1 @
eric
.anq
uetil
@
22
// ~ pointent ou référencent le même objet
Les types primitifs
Tous les éléments manipulés en Java sont des objets
Rappels
p jsauf les types dit numériques ou primitifs
Les types numériques ou primitifs
Définition Définition
byte, boolean, char, short, int, long, float, double;
La manipulation de type numérique : // valeur La manipulation de type numérique : // valeur
On manipule des valeurs et non plus des identificateurs
int a = 1 ;
i t b // k i l ti t d d b 1 1
a 1int b = a ; // ok, manipulation standard b=1; a=1
b = 10 ; // ok, manipulation standard b=10; a=1b 1
Les types numériques possèdent des classes associées (type objet)
char c = 'x';
Ch t C Ch t (' ')
@iri
sa.f
r
Character cC = new Character('x');
Integer Inte=new Integer(10);
int i = Inte.intValue();'x'cC @
c 'x'
eric
.anq
uetil
@
23
xcC @
Exemple : la classe Point
public class Point {
Rappels
public class Point {private int _x;private int _y;
/** déplacement du point par rapport aux coordonnées* du vecteur (x,y) passé en paramètre*/
/** fonction d'acces* abscisse du point ...*/
public int x() {
public void deplace(int dx,int dy) { _x += dx;_y += dy;
public int x() { return _x;
}/** fonction d'acces
}
public static void main(String[] args) {
* ordonnée du point*/
public int y() { return y;
Point p1=new Point(10,10);Point p2=new Point(20,20);System.out.println("p1 : ("+p1.x()+","+p1.y()+")");System out println("p2 : ("+p2 x()+" "+p2 y()+")");return _y;
}
/** constructeur de point à partir
System.out.println("p2 : ("+p2.x()+","+p2.y()+")");p2.deplace(1,1);System.out.println("p2 apres deplacement de (1,1)
: ("+p2 x()+" "+p2 y()+")");
@iri
sa.f
r
* de ses coordonnées x et y*/
public Point(int x,int y) { x = x;
: ( +p2.x()+ , +p2.y()+ ) );}
}p1 : (10,10)
eric
.anq
uetil
@
24
_x = x;_y = y;
}p2 : (20,20)
p2 apres deplacement de (1,1): (21,21)
Invocation des méthodes et attributs / this
Dans la même classe : sur l’objet implicite (this)
Rappels
Dans la même classe : sur l objet implicite (this)
class Point {…public void initOrigine() { // positionne le point courant à l ’origine
_x=0; _y=0; // this._x=0 ; this._y=0;}
D l diffé t bj t li it
}}
Dans une classe différente : sur un objet explicite
class Figure {…private Point ref; // point de référence de la figure
@iri
sa.f
r
...public void translate (int x, int y) {
ref.deplace(x,y); // manipulation explicite de l’objet réf} // par une méthode publique
eric
.anq
uetil
@
25
} p p q// this.ref.deplace(x,y);
}
Surcharge de méthodes
Surcharge
Rappels
g On surcharge une méthode en gardant le même nom et le même type de
retour mais en changeant les paramètres (type et/ou nombre <=> signature)
class Point {private int _x;private int y;private int _y;
public int x() { return _x; }bli i t () { t }public int y() { return _y; }
public void deplace (int dx, int dy) { Le compilateur choisit la méthodeen fonction de sa signature
_x += dx; _y += dy; // ok}
public void deplace (int d) {
Point p1 = new Point() ;
p1 deplace(10 15 );
en fonction de sa signature
@iri
sa.f
r
public void deplace (int d) {_x += d; _y += d; // ok
}
p1.deplace(10 , 15 );
p1.deplace(10 );
eric
.anq
uetil
@
26
...}
Paramètres des méthodes
class Base {
Rappels
class Base {
public void chg1(double a) { // les types primitifs sont passés par VALEUR
a = 11.1;
2.0a
a ;
} // pas d ’effet en dehors de la procédure
public void chg2(Point p) { // les objets sont modifiablespublic void chg2(Point p) { // les objets sont modifiables// par l'intermédiaire de leur référence
p.deplace(2,2);
} // effet en dehors de la procédure
recopie des valeurs @p
} p
public static void main (String[] args) {double a=2.0;Base b1 = new Base(); p1
recopie des références
@Base b1 = new Base();Point p1=new Point (10,10);
Point p2=p1;( ) // ( ) f
2.0a
p1 @
recopie des références
@iri
sa.f
r
b1.chg1(a); // a (valeur) ne sera pas modifiéb1.chg2(p1); // Point p1 a été modifié (déplacement)
// ce qui engendre la mise à jour de p2}
2.0a
@p2
eric
.anq
uetil
@
27
}
Paramètres des méthodes (bis)
En java tous les paramètres sont passés par VALEUR
Rappels
En java, tous les paramètres sont passés par VALEURclass Base {
public void swap(double s) {
double temp = val; val = s; s = temp;double temp = _val; _val = s; s = temp;
} // s = temp; pas d ’effet en dehors de la procédure
double _val;
}
NB : les valeurs (identificateurs) sont assimilables à des pointeurs( ) p
class Base {
public void swap(Base b) {
double temp = val; val = b val; b val = temp;
Identificateur sur un objet de type base
double temp _val; _val b._val; b._val temp;
// b._val = temp; effet en dehors de la procédure
b = new Base(); // ok mais sans influence sur l'extérieur
}
@iri
sa.f
r
on peut modifier l’objet associé à l’identificateur passé en paramètre
double _val;
}
eric
.anq
uetil
@
28
p j p p
on ne peut cependant pas redéfinir les identificateurs pour l’extérieur !
Encapsulation et contrôle d’accès
2 premiers niveaux de protection pour les membres d’une classe :
Rappels
2 premiers niveaux de protection pour les membres d une classe :
private :
les membres privés ne sont pas accessibles à l’extérieur de la classe
public :
les membres publics sont accessibles partout où la classe est accessiblep p
class Point {class Point {private int _x;private int _y;
Point p1 = new Point() ;
public int x() { return _x; }public int y() { return _y; }public void deplace (int dx int dy) {
Point p2 = new Point(10,10);
p1._x =10; // erreur
@iri
sa.f
r
public void deplace (int dx, int dy) {_x += dx; _y += dy; // ok
}...
p1.deplace(p2._x , p2._y ) ; // erreur
p1.deplace(p2.x() , p2.y() ); // ok
eric
.anq
uetil
@
29
...}
Définition d’une classe : résuméRappels
Les attributs publics et privés sont é ifié h b
class Point {
public Point (int x int y) {spécifiés pour chaque membre
L défi i i d f i
public Point (int x, int y) {
_x = x;
_y = y; La définition des fonctions
membres est effectuée dans la définition de la classe
}
public void deplace (int dx, int dy){_x += dx ;
Les données membres sont
_y += dy;
}
public int x() { return x; }initialisées par défaut
public int x() { return _x; }
public int y() { return _y; }
@iri
sa.f
r
Remarques : il n ’y a pas de point virgule à la fin de la définition de classe
private int _x;
private int _y;
}
eric
.anq
uetil
@
30
}
► Unité de ► Unité de compilation
Unités de compilation Fichier
Unité de compilation Fichier : MaClasse java Unité de compilation Fichier : MaClasse.java une seule classe peut être publique dans un fichier
= interface externe
tt l èd l bli t i t l ê l fi hi cette classe possède alors obligatoirement le même nom que le fichier
public class MaClasse { }
Compilation en Java : javac une unité de compilation .java des fichiers bytecode
(un .class par classe)(un .class par classe)
javac MaClasse.java
I t ét ti ja a Interprétation : java fichiers bytecode : instructions destinées à la machine virtuelle
java MaClasse
@iri
sa.f
r
java MaClasse
eric
.anq
uetil
@
32
Exemple d’unité de compilation / main
class Auxiliaire {
...
Fichier : MaClasse.java
public static void main (String[ ] args) {
Auxiliaire x = new Auxiliaire ();
...
}
}
public class MaClasse {
...
public static void main (String[ ] args) {
MaClasse x = new MaClasse();
...
}
}
@iri
sa.f
r
java MaClasse // appel à MaClasse.main()
java Auxiliaire // appel à Auxiliaire main() (test unitaire!)
Test unitaire des classes
eric
.anq
uetil
@
33
java Auxiliaire // appel à Auxiliaire.main() (test unitaire!)
P k► Packages
Utilisation des Packages : espace de nommage
Le code java est partitionné en différents Packages Le code java est partitionné en différents Packages
ex : java.util // regroupe différentes classes utilitaires
java.applet // regroupe les classes utiles à la programmation d ’applet (programme java pour Internet)
Accès aux classes des Packages Accès aux classes des Packages
Pour accéder aux classes des packages il faut accéder à leur nom
soit en utilisant le nom étendusoit en utilisant le nom étendu
java.util.Vector v = new java.util.Vector( );
soit en important le nommage de la classe du package
import java.util.Vector;
Vectorv = new Vector ( );
@iri
sa.f
r
soit en important l’espace de nommage du package entier
import java.util.*;
Vectorv = new Vector ( );
eric
.anq
uetil
@
35
Vectorv = new Vector ( );
Définition de Package - contrôle d’accès
Définition d'un package // Répertoire p g p Si aucun Package n'est mentionné, toutes les classes définies dans le même
répertoire appartiennent à un même package implicite
Package explicite / ex : fichier MaClass.javaPackage explicite / ex : fichier MaClass.java
package malibrairie; // première instruction du fichier
public class MaClass { ... } // même nom que le fichier
Visibilité des classes La classe "Public" (unique / fichier) : accessible à l'extérieur du package
L t l t tili bl d l k Les autres classes ne sont utilisables que dans le package
package P1;
Package P1
package P2;
Package P2
package P1;
public class CA {
CB oB; // ok accès dans} // le même package
package P2;import P1.*;
public class CC {
@iri
sa.f
r
} // le même package
package P1;
class CB {
CA obA; // ok accès// classe publique
CB obB; // ERREUR !
eric
.anq
uetil
@
36
class CB {
CA oA; // ok accès} // classe publique
// package différent}
► Égalité d'objets ► Égalité d objets (1ère approche)
Égalité d'objets (surcharge)
Opérateur == p Teste l’égalité des références (identificateurs) des objets
Ne considère jamais l’égalité du contenu d’un objet
String s "co co "String s ="coucou";
if (s == "coucou") … // comparaison des références !!!
Opérateur equalsOpérateur equals
L’opérateur equals par défaut (de la classe de base Object) opère une
comparaison sur les références.
Il a été redéfini pour beaucoup de classe de la bibliothèque
if (s.equals("coucou")) … // ok en Java
Ecriture d’un opérateur equalsEcriture d un opérateur equals
Normalement : redéfinir l’opérateur equals de la classe « Object »
Cf. redéfinition/equals
@iri
sa.f
r
Class Point {
public boolean equals (Point p) // ici surcharge <> redéfinition
q
En attendant :
possibilité de le surcharger
eric
.anq
uetil
@
38
// ici surcharge <> redéfinition{ return _x== p._x && _y == p._y ; }
...}
M b t ti► Membre statique
Membres statiques : static
Membres d’une classe (attributs ou méthodes)Membres d une classe (attributs ou méthodes) partagés par l’ensemble des instances de la classe
Invocation sur une classe et non sur un objet
M bpublic class Point { private int _x;private int _y;
Membre statique
private static int nbPoint=0;
public static void nbPointC(){System out println("nb d'objets Point créés : " + nbPoint);System.out.println("nb d'objets Point créés : " + nbPoint);
}…public Point(int x int y) {
public static void main(String args[]) {public Point(int x,int y) {
_x = x; _y = y;nbPoint++;
}
Point p1= new Point(10,10);Point p2= new Point();Point p3= p2;Point nbPointC();
@iri
sa.f
r
}public Point() { // constructeur par défaut
_x = 0 ; _y = 0;nbPoint++;
Point.nbPointC();}
nb d'objets Point créés : 2
eric
.anq
uetil
@
40
} …
nb d objets Point créés : 2
D é t t► Donnée constante
Données constantes : final
Les constantes sont des composants de classeLes constantes sont des composants de classe déclarés : final
La valeur d'une constante n'est attribuée qu'une fois au cours de l'exécution :qu une fois au cours de l exécution : soit à l'endroit de sa déclaration soit dans les constructeurs de la classe où elle est définie
permet d’initialiser la constante en fonction de l’objet instancié… permet d initialiser la constante en fonction de l objet instancié ...
class A {
public static final int UN=1; // constante et statiquepublic static final int UN=1; // constante et statique // initialisée une fois pour toute
public final int Xorig;
public final A copain; // l'objet sera modifiable mais pas sa référence...
A(int x, A c) {
@iri
sa.f
r
A(int x, A c) {
Xorig=x; // initialisé une fois pour toute / objet créé
copain=c; // idem au niveau de la référence} // NB: l’objet référencé peut être modifié
eric
.anq
uetil
@
42
} // NB: l’objet référencé peut être modifié...
}
L’ é ti► L’agrégation
Agrégation : classe Point / Rectangle
1er pas vers un diagramme de classes UML 1er pas vers un diagramme de classes UML Notation (membres) : - : privé + : publique _ : static
Association : connexion sémantique bidirectionnelle entre deux classes
Agrégation (faible) : association non symétrique qui exprime une relation de type : ensemble / élément
Association de type agrégation " ensemble / élément " (losange blanc) :
Cad : un rectangle contient 2 Points"
Classe
Att ib t
Multiplicité
Attributs
MéthodesMéthodes
@iri
sa.f
rLa flèche précise que seul le rectangle est "conscient" des Points qu'il possède
eric
.anq
uetil
@
44
des Points qu il possède
Agrégation : exemple de la classe Rectangle
Agrégation : abstraction et réutilisation d'un concept Agrégation : abstraction et réutilisation d un concept
La classe Rectangle utilise la classe point dans sa définition
public class Rectangle {
private Point p_hg;
private Point p bd;
public static void main(String args[]) {
Point p1=new Point(5,5);private Point p_bd;
Rectangle(Point p1, Point p2) {
p_hg = p1 ;
Rectangle r1=new Rectangle (p1,new Point(10,10));
r1.affiche();
r1 deplace(1 1);p_bd = p2 ;
}
public void deplace(int dx, int dy) {
r1.deplace(1,1);
System.out.println("deplacement");
r1.affiche();S t t i tl ("P i t " 1 () " " 1 ()) // NB
p_hg.deplace(dx,dy);
p_bd.deplace(dx,dy);}
System.out.println("Point : " + p1.x()+","+p1.y()); // NB}
Rectangle : (5 5) (10 10)
@iri
sa.f
r
}
public void affiche(){
System.out.println("Rectangle : (" +
p hg x()+" "+p hg y() +
Rectangle : (5,5) (10,10)
deplacement
Rectangle : (6,6) (11,11)
eric
.anq
uetil
@
45
p_hg.x()+ , +p_hg.y() +
") (" + p_bd.x()+","+p_bd.y()+")");} …
g ( ) ( )
Point : 6,6
N ti d i► Notion de recopie
Référence : copie superficielle
Problème : création d'un carré à partir d'un point
a
p1 Problème : création d un carré à partir d un point
public class Rectangle {private Point p hg;
public class Point
{ b
dprivate Point p_hg;private Point p_bd;
Rectangle (Point p1, Point p2) {
…
public Rectangle faireRectangle (int d) {
Point a= this ; // pas de recopieRectangle (Point p1, Point p2) {
p_hg = p1 ; p_bd = p2 ; // ici pas de recopie
}
public void affiche(){
a.deplace(-d/2,-d/2);
Point b= this ; // pas de recopie
b.deplace(d/2,d/2);public void affiche(){
System.out.println("Rectangle : (" +
p_hg.x()+","+p_hg.y()+
Rectangle r=new Rectangle(a,b);
return r;
} }") (" + p_bd.x()+","+p_bd.y()+")");
}
public static void main(String args[]) {
} }
r1@this
@iri
sa.f
r
p ( g g []) {
Point p1=new Point(5,5);
Rectangle r1 = p1.faireRectangle(10);
r1 affiche();
@a @
@
p_hg
eric
.anq
uetil
@
47
r1.affiche();}
}Rectangle : (5,5) (5,5) @b @ p_bd
Référence : notion de copie en profondeur
Solution : recopie des points public class Point {
ap1
Solution : recopie des points Avec un "constructeur par recopie" Avec la notion de clonage
(cf. après)
public class Point { /** constructeur par recopie
* permet de construire un point à partir * d'un autre point passé en paramètre
bd
public class Rectangle { // idemprivate Point p_hg;private Point p bd;
*/public Point(Point p) {
_x = p.x();y = p y();private Point p_bd;
Rectangle (Point p1, Point p2) {
p hg = p1 ; p bd = p2 ;
_y p.y();nbPoint++;
} …
public Rectangle faireRectangle (int d) {p_hg = p1 ; p_bd = p2 ;
} // ici pas de recopie
…
p g g ( ) {
Point a= new Point(this) ; // recopie
a.deplace(-d/2,-d/2);
Point b= new Point(this) ; // recopiepublic static void main(String args[]) {
Point p1=new Point(5,5);
Rectangle r1 = p1.faireRectangle(10);
Point b= new Point(this) ; // recopie
b.deplace(d/2,d/2);
Rectangle r=new Rectangle(a,b);
@iri
sa.f
r
r1.affiche();}
}
return r; }
Rectangle : (0,0) (10,10)r1@this
eric
.anq
uetil
@
48
@a
@b
@
@
p_hg
p_bd
►Exercice C ti d’ Conception d’une
classe Polygoneclasse Polygone
Définition de la classe Polygone
Définition : classe polygone : Définition : classe polygone :
un polygone sera représenté par un tableau d’objets Point
la taille du polygone sera définie lors de sa construction
les points du polygone sont ensuite définis un par un à l’aide d’une méthode les points du polygone sont ensuite définis un par un à l’aide d’une méthode
une méthode permettra de déplacer (translater) un polygone
_coin
@
@@ p0
p1
@ p2
@iri
sa.f
rer
ic.a
nque
til@
50
Diagramme de classes : Point / Polygone
Diagramme de classes Diagramme de classes
Association de type agrégation (losange blanc):
@iri
sa.f
rer
ic.a
nque
til@
51
Polygone : 1ère version
public class Polygone
public String toString() {String S="";for (int i=0; i<taille(); i++){
public class Polygone{
private Point[] _coins;
public Point coin(int i){ return _coins[i];} ( ; (); ){S+= ("("+ coin(i)+") ");
}return S;
}
public int taille(){ return _coins.length;}
public Polygone(int n) {coins = new Point[n]; }
public static void main(String args[]) {Point p0=new Point(10,10);
_coins new Point[n]; }
/** ajout d'un point dans le polygone * sans recopie */ p ( , );
Point p1=new Point(20,20);System.out.println("p0 :"+p0);System.out.println("p1 :"+p1);Pol gone Pol ne Pol gone(3)
public void set_coin(int i,Point p) { if(0 <= i && i < _coins.length)
_coins[i] = p;} Polygone Poly=new Polygone(3);
Poly.set_coin(0,p0);Poly.set_coin(1,p1);Poly.set coin(2,p0);
}public void deplace(int dx, int dy){
for(int i = 0; i < _coins.length; i++)_coins[i].deplace(dx, dy);
@iri
sa.f
r
y _ ( ,p );
System.out.println(Poly);}
}
p0 :(10 10)
eric
.anq
uetil
@
52
p0 :(10,10)p1 :(20,20)((10,10)) ((20,20)) ((10,10))
Polygone : translation d'un polygone fermé
On peut définir un polygone fermé en insérant en début et en fin du Polygone le On peut définir un polygone fermé en insérant en début et en fin du Polygone le même Point
Que se passe t’il si l’on déplace ce polygone
Proposer une solution générale pour Proposer une solution générale pour remédier à ce Problème
Modifier en conséquent les classes Point et PolygonePoint et Polygone
Le point référencé 2 fois pest déplacé 2 fois
coin
@
@@ p0
p1
@iri
sa.f
r@
@ p1
eric
.anq
uetil
@
53
Polygone : problème de référence
public class Polygone
public String toString() {String S="";for (int i=0; i<taille(); i++){
public class Polygone{
private Point[] _coins;public Point coin(int i){ return _coins[i];} ( ; (); ){
S+= ("("+ coin(i)+") ");}return S;
}
public int taille(){ return _coins.length;}
public Polygone(int n) {_coins = new Point[n];
} }
public static void main(String args[]) {Point p0=new Point(10,10);P i t 1 P i t(20 20)
}
/** ajout d'un point dans le polygone sans recopie
*/Point p1=new Point(20,20);System.out.println("p0 :"+p0);System.out.println("p1 :"+p1);Polygone Poly=new Polygone(3);
public void set_coin(int i,Point p) {
if(0 <= i && i < _coins.length)coins[i] = p; yg y yg ( );
Poly.set_coin(0,p0);Poly.set_coin(1,p1);Poly.set_coin(2,p0);
_coins[i] p;
} …
p0 :(10 10)
@iri
sa.f
r
System.out.println(Poly);System.out.println("-- apres deplacement
de (1,1) de Poly --");
p0 :(10,10)
p1 :(20,20)
((10,10)) ((20,20)) ((10,10))
d l t d (1 1) d P l
eric
.anq
uetil
@
54
( , ) y );Poly.deplace(1,1);System.out.println(Poly);
}
-- apres deplacement de (1,1) de Poly --
((12,12)) ((21,21)) ((12,12))
Polygone : notion de recopie
public class Polygone
public String toString() {String S="";for (int i=0; i<taille(); i++){
public class Polygone{
private Point[] _coins;public Point coin(int i) { return _coins[i];} ( ; (); ){
S+= ("("+ coin(i)+") ");}return S;
}
public int taille() { return _coins.length;}
public Polygone(int n) {_coins = new Point[n];
} }
public static void main(String args[]) {p0=new Point(10,10);1 P i t(20 20)
}
/** Ajout d'un nouveau point :ce point est une recopie du point passé en paramètre. Utilisation duconstructeur par recopie p1=new Point(20,20);
System.out.println("p0 :"+p0);System.out.println("p1 :"+p1);Polygone Poly2=new Polygone(3);
constructeur par recopie.*/
public void set_coin_ok(int i,Point p) {
if(0 <= i && i < coins length) yg y yg ( );Poly2.set_coin_ok(0,p0);Poly2.set_coin_ok(1,p1);Poly2.set_coin_ok(2,p0);
if(0 < i && i < _coins.length)
_coins[i] =new Point(p);}
@iri
sa.f
r
System.out.println(Poly2);Poly2.deplace(1,1);
System out println(" apres deplacement
…
p0 :(10,10)p1 :(20,20)((10 10)) ((20 20)) ((10 10))
eric
.anq
uetil
@
55
System.out.println( -- apres deplacementde (1,1) de Poly2 --");
System.out.println(Poly2);}
((10,10)) ((20,20)) ((10,10)) -- apres deplacement de (1,1) de Poly2 --((11,11)) ((21,21)) ((11,11))
Nouveau diagramme de classes : Point / Polygone
Diagramme de Classes Diagramme de Classes Association : connexion sémantique bidirectionnelle entre deux classes
Agrégation faible : association non symétrique qui exprime une relation de type : ensemble / élément
Agrégation forte (Composition) : le polygone possède des Points qui lui sont propres
Agrégation forte : composition (losange noir) :
:: la destruction du polygone => la destruction de ses Points
@iri
sa.f
rer
ic.a
nque
til@
56
G ti é i► Gestion mémoire
Durée de vie des objets
La portée des variables est liée aux { } = durée de vieLa portée des variables est liée aux { ... } durée de vie
Portée au niveau des types primitifs
class Test {{ i t 12void methodeA {
int a, b;
a=1; b=2;
{ int a=12;{
int a= 10; // erreur en JAVA}
} …}
void methodeB {int a, b; // ok, on n’est pas dans le même bloc
}
…if (a < b) {
int f;f = a ;… // les variables du bloc supérieur
} // sont connues dans les blocs inférieurs} // sont connues dans les blocs inférieurs
f = 0; // la réciproque est fausse} // erreur, f n’est pas connue dans ce bloc
}
@iri
sa.f
r
Portée des objets java {
String s = new String("toto");}
eric
.anq
uetil
@
58
// l'identificateur est hors de portée et on ne peut plus accéder à l'objet// il sera alors détruit automatiquement par le « ramasse miette »
}
Le ramasse miette ou « garbage collector »
« Assure une gestion plus sure de la mémoire »« Assure une gestion plus sure de la mémoire »
Durée de vie : le ramasse miette ou « garbage collector »
Java dispose d’un système de récupération de mémoire automatique quand il
« estime » que l’espace occupé par un objet peut être restitué (<=> plus de
référence sur cet objet).référence sur cet objet).String[] T= new String[10];
{ String s ="toto"; T[0]
attention un objet peut être référencé T[0] = s;
}
// la référence s n'existe plus // mais la chaîne "toto" est accessible par T[0]
à plusieurs endroits
et tant qu'il existe une référence sur un
objet il ne sera pas détruit
Le « ramasse miette » fonctionne en arrière plan par défaut.
La destruction est donc asynchrone (gérée par un thread)
// mais la chaîne toto est accessible par T[0] // donc la mémoire n'est pas libérée
@iri
sa.f
r
La destruction est donc asynchrone (gérée par un thread)
La récupération mémoire peut aussi être invoquée explicitement par le
eric
.anq
uetil
@
59
La récupération mémoire peut aussi être invoquée explicitement par le
programmeur : System.gc()
La méthode finalize()
Méthode finalize()Méthode finalize() Méthode appelée par le ramasse-miettes avant la destruction d'une instance de la
mémoire
P t d libé l Class UneClasse {gestion d'un fichiertemporaire Permet de libérer les ressources
(fichier, socket, etc.)
Elle peut être directement appelée
Class UneClasse {
private File fichTemp= new File("ftemp");
private FileOutputStream flotfichTemp;
temporaire
Appel implicite possible si l'instance n'est plus référencée
et que le ramasse-miettes est
// …
public void finalize() throws IOException {et que le ramasse miettes est entré en action
Attention
flotFichTemp.close() // fermeture
fichTemp.delete(); // efface le fichier} }Attention
On ne peut pas prédire quand le ramasse-miettes va entrer en action !
Appel explicite possible (en tâche de fond) avec : System.gc()
L éth d S t Fi li ti ()
@iri
sa.f
r
La méthode System.runFinalization()
Lance le ramasse-miettes et attend que les méthodes finalize() soient invoquées avant de rendre la main
eric
.anq
uetil
@
60
La fin d'un programme n'implique pas forcement l'appel des finalize() !
Pour forcer l'appel à tous les finalize(): System.runFinalization(true)
Hé it► Héritage
Introduction
La notion d'abstraction de réutilisation se traduit par : La notion d abstraction, de réutilisation se traduit par :
La notion de classe
"moule" de construction permettant de créer des objets d'un certain type
La notion d'agrégation
Exemple : la classe Rectangle utilise le concept de Point dans sa définition
=> définition avec un plus haut niveau d'abstraction
La notion d'héritage
Spécialisation d'un concept
Une classe dérivée
adopte,
spécialise
@iri
sa.f
r
spécialise
et/ou enrichit
les membres (structure, méthode) d'une classe de base
eric
.anq
uetil
@
62
Hiérarchisation des concepts
Héritage : diagramme de classe (Personne /employe)
Diagramme de classes Diagramme de classes
Membre ajouté
Méthode spécialiséespécialisée
Méthode remplacée
@iri
sa.f
rer
ic.a
nque
til@
63
Héritage : la classe Personne
La classe Personne La classe Personne
public class Personne {public class Personne {private int _age;private String _nom;
public int age() { return _age;}
public String nom() { return _nom;}
public void miseAJour(int a,String n){_nom=n;_age=a;
public Personne (int a, String n) {_age=a;nom=n;
}
public String toString() {return ("Personne : "+_nom+" : "+
_nom=n;}
public Personne (Personne p) {age=p age;
_age);}… }
@iri
sa.f
r
_age=p._age;_nom=p._nom;
}
eric
.anq
uetil
@
64
Héritage : constructeur / extends
Déclaration de l’héritage Déclaration de l héritage Le mot clé utilisé pour signifier l’héritage : «extends»
En Java on ne peut hériter que d’une seule classe à la fois
Constructeur Le constructeur de la classe
public class Employe extends Personne {
private int _salaire;
de base (ici Personne) est appelépar l’instruction « SUPER »
«super» doit être la
public Employe (int a, String n, int s) {
super(a,n);
_salaire=s;1ère instruction }
public Employe (Personne p, int salaire) {
super(p);
Le(s) constructeur(s) d’une classe dérivée devront faire
l ( ) t t ( )
_salaire=salaire;}
…}
@iri
sa.f
r
appel au(x) constructeur(s) de la classe de base :
implicitement (utilisation du constructeur par défaut)
li it t ( )
}
eric
.anq
uetil
@
65
ou explicitement (super …)
Héritage : des attributs et des méthodes
La classe dérivée hérite automatiquement La classe dérivée hérite automatiquement des attributs et des méthodes de la classe de base
public class Employe extends Personne {
private int _salaire;
…
public Employe (Personne p, int salaire) {
public class Personne {private int _age;private String _nom;
super(p);
_salaire=salaire;}
bli E l (i t St i i t ) {
p g _
public int age(){return _age;}public String nom(){return _nom;}
public Employe (int a, String n, int s) {super(a,n);
_salaire=s;}
…public Personne (Personne p) {
_age=p._age;}
public static void main(String[] args){Personne p1=new Personne(29, "toto");
_nom=p._nom;}
…}
@iri
sa.f
r
( )Employe e2=new Employe(p1,4000);Employe e3=new Employe(20,"titi",1000);System.out.println(e2.nom());System out println(e3 age());
}
eric
.anq
uetil
@
66
System.out.println(e3.age());…}
Héritage : enrichissement d'une méthode Super
Permet d'invoquer le constructeur de la classe de base Permet d'accéder aux membres de la classe de base
public class Employe extends Personne {public class Personne { p p y {
private int _salaire;…
public Employe (Personne p, int salaire) {
p {private int _age;private String _nom;
bli i t (){ t } super(p);salaire=salaire;
}public void miseAJour(int a String n int s) {
public int age(){return _age;}public String nom(){return _nom;}
…public Personne (Personne p) { public void miseAJour(int a,String n,int s) {
miseAJour(a,n); // pas ambiguïtésalaire=s;
}
public Personne (Personne p) {_age=p._age;_nom=p._nom;
}public void miseAJour() { // enrichissement
super.miseAJour(); // ambiguïté levéesalaire=0;
}
}public void miseAJour(int a,String n) {
_nom=n;_age=a;
}
@iri
sa.f
r
}public static void main(String[] args){
Personne p1=new Personne(29, "toto");Employe e2=new Employe(p1,4000);
}public void miseAJour(){
_nom="*";_age=0;
}
eric
.anq
uetil
@
67
e2.miseAJour(e2.age(),e2.nom(),6000);e2.miseAJour(); System.out.println(e2);
…}}
}…}
Héritage : redéfinition d'une méthode
Redéfinition ( surcharge) Redéfinition ( surcharge) Une méthode est redéfinie si elle possède la même signature
(nom + type des paramètres) et le même type de retour que dans la classe de basebase
public class Employe extends Personne {
private int _salaire;public class Personne {
private int _age;i t St i …
public Employe (Personne p, int salaire) {
super(p);
salaire=salaire;
private String _nom;
public int age(){return _age;}public String nom(){return nom;} _salaire=salaire;
}public String toString() {
return ("Employe : " +nom()+" : "+
public String nom(){return _nom;}…
public Personne (Personne p) {age=p age; return ( Employe : nom() :
age()+" / "+ _salaire);} public static void main(String[] args){
Personne p1=new Personne(29 "toto");
_age p._age;_nom=p._nom;
}public String toString() {
@iri
sa.f
r
Personne p1=new Personne(29, "toto");System.out.println(p1); // toString de PersonneEmploye e2=new Employe(p1,4000);System out println(e2); // toString de Employe
return ("Personne : "+_nom+" : "+_age);
} …
eric
.anq
uetil
@
68
System.out.println(e2); // toString de Employe…}
}
Héritage : redéfinition et attachement dynamique
La redéfinition est particulièrement intéressante quand elle est utilisée avec la p qnotion d’attachement dynamique / Polymorphisme L’attachement dynamique (mécanisme implicite de Java) permet à la JVM de choisir la
bonne méthode en fonction du type réel (de la classe) de l'objet appelant
public class Employe extends Personne {
private int _salaire;
public class Personne {private int _age;
i S i …public Employe (Personne p, int salaire) {
super(p);
salaire=salaire;
private String _nom;…
public Personne (Personne p) {age=p. age; _salaire=salaire;
}public String type() {
return "Employe";
_age p._age;_nom=p._nom;
}public String type() {
return "Personne";p y
}public static void main(String[] args){
Personne p1=new Personne(29, "toto");E l 2 E l ( 1 4000)
return "Personne";}
…}
type de e2 : Employe
type de p1 : Personne
t d 3 E l
@iri
sa.f
r
Employe e2=new Employe(p1,4000);Personne p3=e2;System.out.println("type de e2 : "+e2.type());System out println("type de p1 : "+p1 type());
type de p3 : Employe
@Obj pers
p1: Réf sur Pers.
eric
.anq
uetil
@
69
System.out.println( type de p1 : +p1.type());System.out.println("type de p3 : "+p3.type());
…}
Obj emp@
@p3: Réf sur Pers.
e2: Réf sur Empl.
Héritage : exemple d'exploitation de l’attachement dynamique
Utilisation d'un tableau de <Personne> Nb: les <Employe> sont aussi des <Personne> On met dans le tableau des objets de type <Employe> et <Personne> L’attachement dynamique permet de manipuler les éléments du tableau de personnes
en fonction de leur classe !en fonction de leur classe !
public class Employe extends Personne {
private int _salaire;bli l P { …
public String type() {return "Employe";
}
public class Personne {private int _age;private String _nom;
}public static void main(String[] args){
Personne p1=new Personne(29, "toto");Personne p2=new Personne(27, "tata");
public int age(){return _age;}public String nom(){return _nom;}
…Employe e1=new Employe(29, "titi",7000);Personne[] tabPers= new Personne[3];tabPers[0]=p1;t bP [1] 2
…public String type() {
return "Personne";}
@iri
sa.f
r
tabPers[1]=p2;tabPers[2]=e1;for (int i=0; i< tabPers.length; i++) {
System out println( tabPers[i] + " / type = "
…}
Personne : toto : 29 / type = Personne
eric
.anq
uetil
@
70
System.out.println( tabPers[i] + / type = + tabPers[i].type() );
} …}
Personne : tata : 27 / type = Personne
Employe : titi : 29 / 7000 / type = Employe
Héritage : accès aux membres propres de l'objet dérivé
Accès aux membres propres d'un l'objet dérivé Accès aux membres propres d un l objet dérivé via une référence de type de la classe de base Vérifier le type de l'objet : sinon risque d'erreur à l'exécution Faire un CAST / sinon erreur à la compilationp
public class Employe extends Personne {
private int _salaire;
public class Personne {private int _age;private String nom;
Méthode spécifique…public int salaire() { return _salaire;}public String type() {
return "Employe";}
private String _nom;…
public String type() {return "Personne";
Méthode redéfinie
}public static void main(String[] args){
Personne p1=new Personne(29, "toto");Personne p2=new Personne(27, "tata");
;}
…}
Vérification du type de l'objet / Polymorphisme
Personne p2 new Personne(27, tata );Employe e1=new Employe(29, "titi",7000);Personne[] tabPers= new Personne[3];tabPers[0]=p1; tabPers[1]=p2; tabPers[2]=e1;
Cast :Réf. sur Personne -> Réf. sur Employe
@iri
sa.f
r
for (int i=0; i< tabPers.length; i++) { …
if ((tabPers[i].type()).equals("Employe")) {System.out.println("Employe " + i
Personne : toto : 29 / type = Personne
Personne : tata : 27 / type = Personne
eric
.anq
uetil
@
71
System.out.println( Employe i + " salaire " + ((Employe)tabPers[i]).salaire());
}}
yp
Employe : titi : 29 / 7000 / type = Employe
Employe 2 salaire 7000
Héritage : instanceof
Vérifier le type de l'objet référencé Vérifier le type de l objet référencé Utilisation de la méthode Java : instanceof
public class Employe extends Personne {
private int _salaire;…public int salaire() { return salaire;}
public class Personne {private int _age;private String _nom;
public int salaire() { return _salaire;}public String type() {
return "Employe";}public static void main(String[] args){
…public String type() {
return "Personne";}
public static void main(String[] args){Personne p1=new Personne(29, "toto");Personne p2=new Personne(27, "tata");Employe e1=new Employe(29 "titi" 7000);
…}
Vérification du type de l'objet / instanceof
Cast : Employe e1 new Employe(29, titi ,7000);Personne[] tabPers= new Personne[3];tabPers[0]=p1; tabPers[1]=p2; tabPers[2]=e1;
f (i t i 0 i t bP l th i ) {P t t 29 / t P
Cast :Réf. sur Personne -> Réf. sur Employe
@iri
sa.f
r
for (int i=0; i< tabPers.length; i++) {if (tabPers[i] instanceof Employe)
System.out.println("Employe " + i + " salaire "
(( ) ) ())
Personne : toto : 29 / type = Personne
Personne : tata : 27 / type = Personne
Employe : titi : 29 / 7000 / type = Employe
eric
.anq
uetil
@
72
+ ((Employe)tabPers[i]).salaire());} …
}
p y yp p y
Employe 2 salaire 7000
C t ôl d’ è► Contrôles d’accès
Synthèse des différents contrôles d’accès en Java
Contrôle d’accès des membres d’une classe Contrôle d accès des membres d une classe membre public
tout le monde peut y accéder de partout
b é i ( ll l ti d’ i) membre sans préciser (rappelle la notion d’ami)
seules les classes du même package peuvent y accéder (visibilité au niveau package)
membre protected
toutes les classes du même package peuvent y accéder ! En plus les classes dérivées (même de packages différents) peuvent y accéder( p g ) p y
membre private
seuls les membres de la classe peuvent y accéder
Droits d'accès private (sans préciser) protected public
depuis la classe ok ok ok ok
@iri
sa.f
r
depuis la classe ok ok ok ok
depuis une classe non ok ok okdu même package
eric
.anq
uetil
@
74
depuis une classe non non ok si classe okd'un package différent dérivée
L l Obj t► La classe Object
Définition de java.lang.Object
Toutes les classes JAVA héritent par défaut de la classe «Object» Toutes les classes JAVA héritent par défaut de la classe «Object»
la classe Object est donc la racine hiérarchique de toutes les classes
class Personne { … } // implicitement équivalent à
Quelques méthodes de la classe Object (redéfinissables)
class Personne extends Object { … }
Quelques méthodes de la classe Object (redéfinissables)
Object
Object()
String toString() - représentation d'un objet sous forme de chaîne
@iri
sa.f
r
Object clone()
boolean equals(Object)- pour la création de la copie d'un objet (cf. notion de clonage…)
- pour définir un critère d'égalité entre deux objets
eric
.anq
uetil
@
76
…
► Égalité d'objets g j(surcharge
/redéfinition)/redéfinition)
Égalité d'objets (surcharge de equals)
Ecriture d’un opérateur equals FigureEcriture d un opérateur equals Possibilité de le surcharger
=> pas de polymorphisme
- deplacer()
- dessiner()
- dilater()
Figure
Point EllipsePolygone
class Point extends Figure{
//…
+ Point()
+ clone()
+ deplacer()
+ dessiner()
+ dilater()
+ Ellipse()
+ centre()
+ deplacer()
+ dessiner()
+ dilater()
+ Polygone()
+ coin()
+ deplacer()
+ dessiner()
+ dilater()
public boolean equals(Point p){ return ((p._x==_x) && (p._y==_y)); }
public static void main(String[] args){
Figure[] fig = new Figure[4];
fi [0] Elli ( P i t(150 150) 100 100)
Rectangle
()
+ equals()
+ main()
+ x()
+ y()
()
+ xrayon()
+ yrayon()
()
+ set_coin()fig[0] = new Ellipse(new Point(150, 150),100,100);
fig[1] = new Rectangle(new Point(140, 140), new Point(160, 160));
fig[2] = new Point(130, 200);
fig[3] = new Point(1 2);
+ Rectangle()
gfig[3] new Point(1, 2);
for (int i=0; i< fig.length; i++){
System.out.println(fig[i].equals(new Point(1,2)));
}false
f l
@iri
sa.f
r
System.out.println(".............");
for (int i=0; i< fig.length; i++){
if (fig[i] instanceof Point) {
S t t i tl (((P i t)fi [i]) l ( P i t(1 2)))
false
false
false
.............
eric
.anq
uetil
@
78
System.out.println(((Point)fig[i]).equals(new Point(1,2)));}
}}
.............
false
true
Égalité d'objets (redéfinition de equals)
Ecriture d’un opérateur equals FigureEcriture d un opérateur equals Possibilité de le redéfinir / class Object
=> polymorphisme
- deplacer()
- dessiner()
- dilater()
Figure
Point EllipsePolygone
class Point extends Figure{
public boolean equals(Object p){
if (p instanceof Point) {
+ Point()
+ clone()
+ deplacer()
+ dessiner()
+ dilater()
+ Ellipse()
+ centre()
+ deplacer()
+ dessiner()
+ dilater()
+ Polygone()
+ coin()
+ deplacer()
+ dessiner()
+ dilater()
return ((((Point)p)._x==_x) && (((Point)p)._y==_y)); }
else return false;}public static void main(String[] args){
Rectangle
()
+ equals()
+ main()
+ x()
+ y()
()
+ xrayon()
+ yrayon()
()
+ set_coin()public static void main(String[] args){
Figure[] fig = new Figure[4];
fig[0] = new Ellipse(new Point(150, 150),100,100);
fig[1] = new Rectangle(new Point(140, 140), new Point(160, 160));
+ Rectangle()
g
fig[2] = new Point(130, 200);
fig[3] = new Point(1, 2);
for (int i=0; i< fig.length; i++){
System out println(fig[i] equals(new Point(1 2)));false
f l
@iri
sa.f
r
System.out.println(fig[i].equals(new Point(1,2)));
}
System.out.println(".............");
for (int i=0; i< fig.length; i++){
false
false
true
.............
eric
.anq
uetil
@
79
( ; g g ; ){
if (fig[i] instanceof Point) {
System.out.println(((Point)fig[i]).equals(new Point(1,2)));}}}
.............
false
true
Cl b t it► Classe abstraite
Classe et méthode abstraites : abstract
Une classe abstraite Une classe abstraite elle possède 0 ou plusieurs méthodes abstraites une classe déclarée abstraite ne peut pas être directement instanciée
Une méthode abstraite Une méthode abstraite elle possède un corps vide si une méthode est abstraite => classe déclarée comme abstraite objectif : forcer les classes dérivées (concrètes) à redéfinir toutes les objectif : forcer les classes dérivées (concrètes) à redéfinir toutes les
méthode(s) abstraites de la classe de base abstraite
Exemple de diagramme de classes Exemple de diagramme de classes
Classe abstraite (italique) HumainClasse abstraite (italique)
Méthodes abstraites (italique)
Humain
@iri
sa.f
rer
ic.a
nque
til@
81
Exemple de Classe et méthode abstraites
H i
b l X { }
Humain
abstract class X { … }
public class Etudiant extends Humain {
abstract class Humain {
public class Etudiant extends Humain {private int _age;private String _nom;
public int age(){return age;} // redef. obligatoireabstract String nom();
abstract int age();
public String toString() {
p g (){ _ g ;} g
public String nom(){return _nom;} // redef. obligatoire
public Etudiant (int age, String nom) {age=age;
@iri
sa.f
r
return nom();}
}
_ g g ;_nom=nom;
}public static void main(String[] args){
Et di t 1 Et di t(29 "t t ")
eric
.anq
uetil
@
82
Etudiant e1=new Etudiant(29, "toto");System.out.println(e1);
} …}
I t f► Interface
Interface Java : implements
éf Définition
Une interface Java est une sorte de classe abstraite "pure" :
Sans donnée (sauf static et final)Sans donnée (sauf static et final)
Possède seulement des fonctions abstraites (publiques)
Une classe peut "implémenter" plusieurs Interfaces ( héritage)
Lorsqu'une classe implémente une interface elle garantit de définir toutes les méthodes de l'interface
<=> elle garantit de respecter public class Personne implements Imprimablegle protocole défini par l'interface
Implantation
{
…
// redéfinition obligatoire Implantation
interface Imprimable {
public void imprime();
// redéfinition obligatoire
// imposée par l'interface Imprimable
public void imprime(){
S t t i tl (thi )
@iri
sa.f
r
public void imprime();
}System.out.println(this);
}
…
eric
.anq
uetil
@
84
public class Employe extends Personne {…}
Exemple d'utilisation d'interface 1/2
On caractérise les classes <Imprimable>
«interface»Imprimable
On caractérise les classes <Imprimable>
avec l'Interface <Imprimable> Par exemple : les classes <Personne> et <Employe>
+ imprime()
- _age: int
- _nom: String
Personnepublic class Personne implements Imprimable {
public void imprime(){ System.out.println(this); } _ g
+ age()
+ nom()
+ Personne()
+ imprime()
public class Employe extends Personne {
//
p p (){ y p ( ) }
…
p ()
+ miseAJour()
+ type()
+ toString()
// …
public static void main(String[] args){
Personne p1=new Personne(29, "toto");
Personne p2=new Personne(27, "tata");
- salaire: int
EmployeImprimable i1=new Employe(29, "titi",7000);
Imprimable i2=p1;
I i bl i3 2
@iri
sa.f
r
_sa a e t
+ salaire()
+ Employe()
+ type()
+ miseAjour()
Imprimable i3=p2;
i1.imprime();
i2.imprime();
i3.imprime();
Employe : titi : 29 / 7000
Personne : toto : 29
Personne : tata : 27
eric
.anq
uetil
@
85
miseAjour()
+ toString()i3.imprime();
}
}
Exemple d'utilisation d'interface 2/2
Exemple avec les classes <Personne> <Employe> et <Rectangle> Exemple avec les classes <Personne> <Employe> et <Rectangle> On peut rassembler dans un tableau
des classes respectant le protocole <Imprimable>
L'interface garantit que tous les objets du tableau g q j(même de nature différente) sont imprimables
interface Imprimable {public static void main(String[] args){
P 1 P (29 "t t ")interface Imprimable {
void imprime();
}
Personne p1=new Personne(29, "toto");
Employe e1=new Employe(29, "titi",7000);
Rectangle r1 = new Rectangle (new Point(1,1) ,
new Point (100,100));
Imprimable[] tabImpression= new Imprimable[3];
tabImpression[0]=p1;public class Rectangleimplements Imprimable {
tabImpression[1]=e1;
tabImpression[2]=r1;
for (int i=0; i< tabImpression.length; i++) {
implements Imprimable {
private Point p_hg;
private Point p_bd;
(){
@iri
sa.f
r
tabImpression[i].imprime();
}} Personne : toto : 29
public void imprime(){
System.out.println("Rectangle : " +
p_hg + " " + p_bd);
eric
.anq
uetil
@
86
Employe : titi : 29 / 7000
Rectangle : (1,1) (100,100)
}
…
Interface : Diagramme de Classes
Diagramme de classes Diagramme de classes
Interface : services offerts par une classeInterface : services offerts par une classe
Lien de réalisation : Personne et Rectangle fournissent l'interface
@iri
sa.f
rer
ic.a
nque
til@
87
Interface et héritage
Héritage classique
Les interfaces peuvent être organisées de manière hiérarchique via le
mécanisme d’héritage.
Interface intFaceA extends intFaceB { …}
On peut avoir un héritage multiple d’interfaces :
interface intFaceA extends intFaceX, intFaceY {…}
@iri
sa.f
rer
ic.a
nque
til@
88
Interface Versus Classe abstraite
Une Interface
spécifie la forme (spécification, définition d'un comportement) de quelque p ( p , p ) q q
chose (d'un concept) ( fournir une implémentation)
Les méthodes de l'interface définissent le protocole (signature) à faire
respecter pour ce concept
Classe abstraite
Une classe abstraite est une classe incomplète qui nécessitera une
spécialisation (une dérivation)
A utiliser pour initialiser une hiérarchisation de classes (classe de base)
@iri
sa.f
rer
ic.a
nque
til@
89
C ll ti J► Collection Java
Les collections Java : Principe
Les collections Les collections
Structures de données de différents types permettant le regroupement d'un "ensemble" d'éléments dans une même entité
Permet le stockage et la manipulation des ces éléments
Les collections en Java2 (outils et boîte à outils) Les collections en Java2 (outils et boîte à outils)
Java2 offre un "framework" pour la gestion des collections
Structuration générique basée sur une hiérarchie d'interfaces
Organisation des structures de données en fonction de leur type
Implémentation de nouvelles structures guidée par les contraintes de généricité (réutilisation et interopérabilité facilité)
Manipulation unifiée des éléments
indépendamment du type de la structure
Algorithmes de base fournis pour les opérations sur les collections
@iri
sa.f
r
Algorithmes de base fournis pour les opérations sur les collections
tri, recherche, etc.
eric
.anq
uetil
@
91
Les collections Java : Vector, List, …
Organisation en Java2 :
Gestion homogène des structures de données :interface / classe abstraite / classe concrètes : java.utilinterface / classe abstraite / classe concrètes : java.util
Interface Classes abstraites / concrètes
Collection Set AbstractSet HashSetCollection Set AbstractSet HashSet(collections sans duplication TreeSetd'éléments)
List AbstractList ArrayList(collections ordonnées, Vectorduplication possible) ……
Map SortedMap HashMap(collections associant à chaque élément TreeMap
@iri
sa.f
r
(co ect o s assoc a t à c aque é é e t ee apune clé / maintient des clés selon un ordre …) …
autre Stack Arrays
eric
.anq
uetil
@
92
… autre … Stack, Arrays, Bitset …
Collection Java : l'interface collection
L'interface collection L interface collection
Définition d'un protocole minimum pour l'utilisation et la conception d C ll ti Jde Collections en Java
Exemple
add(Object o) pour ajouter un élément à une collection
remove(Object o)
pour retirer une instance d'un élément à une collectiond un élément à une collection
Pas d'implémentation directe en Java
@iri
sa.f
rer
ic.a
nque
til@
93
Collection Java : les interfaces
Racine de l'héritage / concepts génériques
Collection ordonnée, les élémentspeuvent être dupliqués
Collection sans duplication d'éléments
Ensemble triéCollection d'association (clé élément)
@iri
sa.f
r
(clé,élément)
eric
.anq
uetil
@
94
Collection Java : interfaces / classes abstraites
Classes abstraites
Interfaces
@iri
sa.f
rer
ic.a
nque
til@
95
Collection Java : diagramme de classes du framework
Classes abstraites
Interfaces
Classes concrètes@
irisa
.fr
eric
.anq
uetil
@
96
Collection Java : les iterateurs
L'interface Iterator L interface Iterator Permet le parcours d'une collection
sans connaître le détail de sa structure
L'i t f Li tIt t L'interface ListIterator
spécialisation permettant d'itérerdans les deux sens
// exemple de méthode générique qui fonctionne sur une collection quelque soit son type
public static void Parcour() {
Iterator it = MaCollection.Iterator(); // on récupère un// itérateur sur une// collection// collection
while (it.hasNext()) {// hasNext() vérifie qu'il reste au moins 1 élément à parcourir
@iri
sa.f
r
System.out.println("elts : " + it.next()); // next() retourne le prochain élément dans l'itération si il y// en a un, sinon exception
eric
.anq
uetil
@
97
}
}
Collection Java : un petit exemple
import java util *;import java.util. ;public class ExempleCollection {
static ArrayList maArrayList= new ArrayList(); // idem à un tableau dynamique// Collection de type ArraysList : Liste utilisant un tableau(Array) comme structure de donnéesyp y ( y)public static void init() {
Integer[] tabEnt =new Integer[] { new Integer(2), new Integer(4),new Integer(6),new Integer(8),new Integer(10),new Integer(12) };
List maList = java util Arrays asList(tabEnt);List maList = java.util.Arrays.asList(tabEnt); // utilisation d'une classe "d'aide" sur les Array // la classe Arrays // asList(Object[]) : permet la transformation d'un Array en une Liste
maArrayList.addAll(maList); // insertion de tous les éléments de maList}public static void affiche() {
Iterator it = maArrayList.iterator(); while (it hasNext()) { System out println("elts : " + it next()); }while (it.hasNext()) { System.out.println( elts : + it.next()); }System.out.println("---");
}public static void main (String[] arg) {
@iri
sa.f
r
init();affiche();maArrayList.remove(1); // enlève l'élément situé à l'index 1maArrayList add("coucou"); // ajout d'un élément en plus en fin de Liste
eric
.anq
uetil
@
98
maArrayList.add( coucou ); // ajout d un élément en plus en fin de Listeaffiche();
}}
E ti► Exception
Notion d'erreur / Exception
Différents types d'erreurs Différents types d erreurs
Mauvaise gestion des classes : accès hors tableau, ...
Entrées utilisateurs non valides : effacer un fichier inexistant, ...
Liées aux périphériques : manque de papier dans l'imprimante, ...
Limitation physique : disque plein, ...
...
Le traitement des erreurs / les différentes possibilités
Retourner un code d'erreur
Ne rien faire (absorber l'erreur)
Imprimer des messages d'erreur Imprimer des messages d erreur
Mettre à jour des variables globales d'erreur
Utiliser le mécanisme d'exception unifié et standardisé
@iri
sa.f
r
.... Java supportent le mécanisme de gestion d'exception ...
eric
.anq
uetil
@
100
Traitement des cas d'erreurs exceptionnelles
Le traitement de cas exceptionnel ne peut très souvent être opéré que dans unLe traitement de cas exceptionnel ne peut très souvent être opéré que dans un contexte supérieur à la détection de l’erreur
Mé i d' ti / ti i d' ti Mécanisme d'exception / gestionnaire d'exception Permet de transmettre le problème du traitement de l'erreur dans un contexte
qualifié (de niveau supérieur) pour gérer l'erreur
Simplifie en allégeant le code de la gestion locale des erreurs par une recentralisation des procédures de traitement d'erreurp
Mise en œuvre des exceptions
on déclenche (lance) une exception par l'instruction throw
on capte (attrape) une exception dans un bloc de type try
@iri
sa.f
r
p ( p ) p yp y
on traite (gère) une exception avec l'instruction catch
eric
.anq
uetil
@
101
Exemple : mécanisme d'exception / finally
void methode2 ( ) throws IOExceptionPublic class TestException{ // …
public methode1(){ try
( ) p{
methode3();// …
}
2
{ try{
methode2()//...
void methode3 ( ) throws IOException{
write ( ) // Erreur : exception déclenchée !!!!!
}
1
2
}catch (IOException e){
System out println("Gestion de l'exception");
write (...) // Erreur : exception déclenchée !!!!!//...
}
1
34
System.out.println( Gestion de l exception );...
}catch (Exception e) • Arrêt de l'exécution : lancement de l'exception15 ( p ){ ... }
finally{ // bloc "finally" optionnel
• Transmission du control au bloc supérieur …
• Capture de l'exception par un bloc "catch"
• Traitement de l'exception
2
3
4
@iri
sa.f
r
{ // bloc finally optionnel... }
// suite du code ...
p
• Le bloc "finally" est toujours exécuté : qu'il y ait
capture, propagation ou déroulement normal du
programme
56
eric
.anq
uetil
@
102
}programme
• Le programme reprend après le bloc "finally" 6
Exécution sans exception
Réception / traitement d'une exception
Lorsque qu'intervient une exception (réception par la JVM) Lorsque qu intervient une exception (réception par la JVM) L'exécution normale du programme est arrêté
Recherche du bloc de traitement de public class TestException {de traitement de l'exception (catch)
en local,
public class TestException {
public void test(int i) throws Exception {
if (i==0) throw new Exception("erreur i est égal a 0"); puis on remonte
la liste des appelants
Traitement de l'exception
( )
System.out.println("i == "+ i);
}
Tous les blocs "finally" rencontrés sont exécutés
Reprise du code
public static void main(String[] args){
TestException t = new TestException();
try { Reprise du code t.test(1); t.test(2); t.test(0); t.test(3);
}
catch(Exception e) {
S t t i tl ( tM ())i == 1
@iri
sa.f
r
System.out.println(e.getMessage());}System.out.println("reprise du code");
}
i == 1
i == 2
erreur i est égal a 0
i d d
eric
.anq
uetil
@
103
}}
reprise du code
Lancement d'exceptions / throw
Une exception est lancée par la commande throw e; Une exception est lancée par la commande throw e;
e : est un objet qui DOIT dériver de la classe Throwable
throw new IllegalArgumentException("Pb en lecture");g g p ( )
Spécification obligatoire des exceptions susceptibles d’être lancées
Toute fonction susceptible d'émettre des exceptions "explicites" doit le mentionner (vérification à la compilation ) :
Exceptions levées dans la méthode et non attrapées par celle-ci
Exceptions levées dans des méthodes appelées par la méthode …Exceptions levées dans des méthodes appelées par la méthode …
Exceptions levées et traitées par la méthode puis propagées
public void read(DataInputStream in) throws IOException
U f ti l th
public void read(DataInputStream in) throws IOException
{ ... double s = in.readDouble ( ); // peut générer une exception
... }
@iri
sa.f
r
Une fonction sans clause throws
garantit qu’elle ne va pas générer d’exception explicite
eric
.anq
uetil
@
104
Capture et traitement d'exceptions / try … catch
Capture (bloc try) et traitement d'exceptions (clause catch) Capture (bloc try) et traitement d exceptions (clause catch)
try
{ // code susceptible de déclencher une exception{ // code susceptible de déclencher une exception
}
catch (Type1 id1) { // capture des exception de type Type1// ou type dérivé de Type1
// traitement de l'exception de Type1
}
catch (Type2 id2) { // capture des exception de type Type2 …
// traitement de l'exception de Type2
}
// etc.
Remarques
@iri
sa.f
r
q
Les blocs try encapsulent de nombreux appels de fonctions ...
Le transfert de contrôle est donné à la 1ère clause catch de bon type
Il t ibl d’ l it l ti d’hé it hié hi l
eric
.anq
uetil
@
105
Il est possible d’exploiter la notion d’héritage pour hiérarchiser les exceptions => l'ordre des blocs catch doit respecter l'ordre d'héritage
Retransmission d’une exception
Il est possible de retransmettre une exception Il est possible de retransmettre une exception
try
{ // code
}
catch (Throwable t) // capture tout type d'exception
{ ...
throw t; // retransmet l'erreur courante
}
Si une exception est propagée sans être rattrapée :
Si propagation jusqu'à la méthode "main"
@iri
sa.f
r
public static void main (String[] args) throws Exception
Affichage d'un message d'erreur et de la pile des appels,
Arrêt de l'exécution du programme.
eric
.anq
uetil
@
106
p g
Exception standard en Java
Java possède une hiérarchie d’exceptions standardsp p
ThrowablePossède 2 sous-classes
standards
Exception ErrorA Récupérer :
sous le contrôledu programmeur
Erreur propreà la la machine virtuelle système
……...
du programmeur,Sauf les Runtime
virtuelle, système
Appel d'une méthode abstraite, La machine virtuelle n'a pas
……...IOExceptionRuntimeException
Division par zéro, Dépassement d'indice
La machine virtuelle n a pas assez de mémoire, …
Exception techniques et d'erreurs (Runtime, Error) : un programme n'est pas obligé de lever ces 2 types d'exception (raisons essentiellement pratiques)
Dépassement d indice dans un tableau, …
@iri
sa.f
r
obligé de lever ces 2 types d exception (raisons essentiellement pratiques)
Exception explicite ou applicatives : pour toutes les autres exceptions le programme doit les lever (imposé par le compilateur)
eric
.anq
uetil
@
107
Pour définir de nouveaux types d'exception on hérite en général de java.lang.Exception
Créer vos propres classes d'exceptions : Throwable
Java lang Throwable Java.lang.Throwable
Throwable
String message
Throwable()
Th bl ( t i )
- Message d'erreur décrivant l'exception
- Constructeur avec et sans message d'erreur
Throwable(string s)
String getMessage()
Void printStackTrace()
Void printStackTrace(PrintStream)
- Retourne le message d'erreur
- Imprime sur la sortie standard ou sur un stream, l'exception et la trace de l'exception dans la pile
Exemple de récupération du message de l'exception
Void printStackTrace(PrintStream)
…l exception et la trace de l exception dans la pile
Exemple de récupération du message de l exception
try { ….}
catch (Exception e)
@iri
sa.f
r
catch (Exception e)
{ System.out.println(e.getMessage()); // ou
System.out.println(« Exception » + e); // cf. notion de toString
eric
.anq
uetil
@
108
}
Créer vos propres classes d'exceptions : MonException
Un petit exemple Java Un petit exemple Java
public class MonException extends Exception {
public MonException ( ) { }public MonException ( ) { }
public MonException (String msg) {
super(msg) ;
}
}
public class UneClasse
{ public void g() throws MonException { // ...{ p g() p {
throw new MonException("Origine: fonction g()");
}
public void h() throws MonException { // ... MonException: Origine: fonction g()g();
}
public static void main (String[] args) {
UneClasse C1=new UneClasse();
p g g()
at UneClasse.g(UneClasse.java:9)
at UneClasse.h(UneClasse.java:13)
at UneClasse.main(UneClasse.java:17)
@iri
sa.f
r
UneClasse C1=new UneClasse();
try { C1.h(); }
catch (MonException e) { e.printStackTrace(); }
} }
eric
.anq
uetil
@
109
} }
Exemple complet
class MonException1 extends Exception {
public static void main(String[] args) throws MonException1{TestException C1 = new TestException();try {p p {
public MonException1(String msg) {super(msg);System.out.println("cons MonException1" );
}}
C1.methodeB();} catch (MonException2 e) {
System.out.println("Traitement dans main() : " + e);} finally {}
class MonException2 extends MonException1 {public MonException2(String msg) {
super(msg);System.out.println("cons MonException2" );
}
} y {System.out.println("finally de main()");
}C1.methodeA(1);System out println("fin de main()");}
}public class TestException {public void methodeA(int p) throws MonException1 {
if (p==1) throw new MonException1("p==1: methodeA");
System.out.println( fin de main() );}
if (p==2) throw new MonException2("p==2: methodeA");System.out.println("fin de methodeA");
}public void methodeB() throws MonException1 {
//
cons MonException1cons MonException2
Traitement partiel dans methodeB :// ...try {
methodeA(2);} catch (MonException1 e) {
System.out.println("Traitement partiel
Traitement partiel dans methodeB : MonException2: p==2: methodeA
finally de methodeB
Traitement dans main() : MonException2: p==2: methodeA
@iri
sa.f
r
System.out.println( Traitement partiel dans methodeB : " + e);
throw e;} finally {
System.out.println("finally de methodeB");}
MonException2: p==2: methodeAfinally de main()cons MonException1Exception in thread "main"
MonException1: p==1: methodeA
eric
.anq
uetil
@
110
}System.out.println("fin de methodeB");
}}
MonException1: p 1: methodeAat TestException.methodeA(TestException.java:17)at TestException.main(TestException.java:45)
► Clonage et copie ► Clonage et copie en profondeur
Notion de copie en profondeur
En JAVAEn JAVA
Copie d'identificateur : pas de recopie des objets identifiés
Il faut souvent implanter la recopie (… en profondeur si besoin …)
Gestion des recopies d’objet avec le constructeur par recopie
Rectangle Carre (Point p, int d) {
Point a= new Point(p) ; // constructeur par recopie aPoint a new Point(p) ; // constructeur par recopie
a.deplacer(-d / 2 , -d / 2);
Point b= new Point(p) ; // constructeur par recopie
b.deplacer(d / 2 , d / 2);b
p
Rectangle r=new Rectangle(a,b);
return r;}
bd
Utilisation de la méthode : clone()
Rectangle Carre (Point p, int d) {P i t (P i t) l ()
@iri
sa.f
r
Point a= (Point)p.clone() ;a.deplacer(-d / 2 , -d / 2);Point b= (Point)p.clone() ;b.deplacer(d / 2 , d / 2);
eric
.anq
uetil
@
112
Rectangle r = new Rectangle(a,b);return r; // résultat correct
}
La méthode clone( ) de la classe Object
La méthode clone de la classe Object ne fait par défaut que
la réservation mémoirela réservation mémoire
et
la recopie superficielle (ok pour : types primitifs et les objets invariants)
De plusp
clone() est une fonction protégée (surcharge "public" possible)de la classe de base Object.
l’accès à cette fonction est protégé et seules les classes mettant en œuvre l’accès à cette fonction est protégé et seules les classes mettant en œuvre l’interface de balisage Cloneable peuvent y accéder (une sorte d'avertissement)
@iri
sa.f
r=> Implantation explicite de la méthode clone() pour vos classes
eric
.anq
uetil
@
113
Mise en œuvre de la méthode clone()
Implantation de la méthode clone()Implantation de la méthode clone()
l’interface Cloneable doit être mise en œuvre
le contrôle d’accès à cette fonction nécessite la mise en place du traitement d’exception
*gestion d’exception
class Point implements Cloneable
{ public Object clone( ){ p j ( )
{ try { return super.clone(); } // recopie superficielle
catch (CloneNotSupportedException e) { return null; }
}
…
@iri
sa.f
r
private int _x; private int _y;
}
eric
.anq
uetil
@
114
Mise en œuvre de la méthode clone()
Copie en profondeur Copie en profondeur
Les champs « constants » sont implicitement gérés (nombres, string, ...)
Les champs « identificateurs » doivent être clonés (toutes les classes référencées doivent être "récursivement" clonées)
class Rectangle implements Cloneable {
public Object clone( ) {
try {
Rectangle r = (Rectangle)super.clone() ;
r pt hg (Point) pt hg clone() ; // fonction clone() à définirr._pt_hg = (Point) _pt_hg.clone() ; // fonction clone() à définir
r._pt_bd = (Point) _pt_bd.clone() ; // pour la classe Point
return r;
}}
catch (CloneNotSupportedException e) {
return null;
}
@iri
sa.f
r
}
…
}
eric
.anq
uetil
@
115
Clonage et héritage
La notion de « cloneable » est transmise aux classes dérivéesLa notion de cloneable est transmise aux classes dérivées
La méthode super.clone(), l’héritage et l’attachement dynamique
class Niv1 implements cloneable {
public Niv1(int i) { _i=i; }
public Object clone( )
{ try { return super.clone(); } // recopie superficielle
t h (Cl N tS t dE ti ) { t ll }catch (CloneNotSupportedException e) { return null; }
}
…
private int i;private int _i;
}
class Niv2 extends Niv1 {{
private int j; // copie automatique
public Niv2(int i) { super(i); }...
}
@iri
sa.f
r
Quand Niv1.clone() est appelée à travers Niv2.clone() ; Object.clone() est lé à t l () i t ill l Ni 2
}
eric
.anq
uetil
@
116
appelée à travers super.clone() qui travaillera alors avec Niv2
Remarques sur le clonage en Java
Interface CloneableInterface Cloneable
interface Cloneable { }
l Obj tclass Object
{ protected Object clone(){ if (! (this instanceof Cloneable))
throw new CloneNotSupportedException();pp p ();
...
}
La classe Vector : met en œuvre une copie superficielle
...
La classe Vector,… : met en œuvre une copie superficielle
Recopie en profondeur :
faire appel à la méthode clone() (copie superficielle)
@iri
sa.f
r
Vector v2=(Vector)v1.clone();
parcourir le vecteur pour cloner explicitement tous ses éléments
for (int i=0; i<v2.size(); i++)
eric
.anq
uetil
@
117
for (int i 0; i v2.size(); i ) v2.setElementAt((v2.elementAt(i)).clone(), i);
Cl i t ► Classe interne
Classe interne : inner class
Possibilité de déclarer une classe à l'intérieur d'une autre classePossibilité de déclarer une classe à l intérieur d une autre classe Association de la visibilité de bloc avec la visibilité de classe
Accès aux membres de la classe englobante
P t d " h " l l i t lié à i lé t ti Permet de "cacher" les classes internes liées à une implémentation spécifique et de rassembler les classes connexes
Trois déclinaisons des classes internes Classe membre
d'une classe class Englobe { …
class ClasseMembre { ... }
Classe locale à une méthode membre
{ }}
class Englobe { …
void methode() {membre d'une classe
Cl
void methode() {
class ClasseLocale { ... }}
}
@iri
sa.f
r
Classe anonyme définie à l'intérieur d'une expression
class Englobe { …
void methode() {
eric
.anq
uetil
@
119
Ob.addActionListner( new ClasseAnonyme() { ... });}
}
Classe interne : membre d'une classe
Une classe membre interne peut être déclarée comme : public privateUne classe membre interne peut être déclarée comme : public, private, protected.
Elle a accès aux membres (attributs/méthodes), même privés, de la classe l'englobantl englobant
class Englobe {
private int att1;private int att1;private class LocalePr {
private int att2;
bli id t t() {public void test() {
att2=att1; // équivalent à this.att2=Englobe.this.att1;} ...
}
public class LocalePu { ... }
private LocalePr vpr; // utilisation de la classe interne privée
@iri
sa.f
r
private LocalePr vpr; // utilisation de la classe interne privée...
}…
eric
.anq
uetil
@
120
Englobe E = new Englobe();
Englobe.LocalePu vpu= E.new LocalePu(); // classe interne publique
Classe interne : locale
Classes internes déclarées dans un bloc de codeClasses internes déclarées dans un bloc de code Uniquement visibles et utilisables dans leur bloc
(idem aux variables locales)
Ell t è l i bl l l "Fi l" d l bl Elles ont accès en plus aux variables locales "Final" de leur bloc garantit la cohérence avec les variables locales
Elles ne peuvent pas être spécifiées comme (public, private, …)
class Englobe2 {private int att1;void methode() {void methode() {
final int att2=2;int att3=2;class ClasseLocale {class ClasseLocale {
private int att;public void test() {
att=att1;
@iri
sa.f
r
att att1;att=att2;
// att=att3; // erreur (att3 non final)}
}
eric
.anq
uetil
@
121
}}
}
Classe interne : anonyme
Classe locale sans nom Contraction(combinaison) : définition et instanciation d'une classe Souvent utilisée dans le contexte de la gestion des évènements
class Englobe3 {private int att1; public void test(Point P) {
System out println(P); P deplacer(1 1); System out println(P);System.out.println(P); P.deplacer(1,1); System.out.println(P);}public void test2() {
test( new Point(10,10) { bli i t
Classe anonyme dérivée de la classe Point
public int _z;public void deplacer(int dx, int dy) {
_x += dx; _y += dy; _z=111;}
Les arguments sont passés au constructeur de la classe de base (Point)
}public String toString() {
return("Point3D : " + x() + " " +y() + " " + _z);}
});
@iri
sa.f
r
});}public static void main(String[] args) {
Englobe3 Eng=new Englobe3();Eng test2();
Point3D : 10 10 0
eric
.anq
uetil
@
122
Eng.test2();}
}
Point3D : 11 11 111
Classe interne : anonyme
Une classe anonyme peut implémenter une interfaceUne classe anonyme peut implémenter une interface
Elle devient alors une classe dérivée de Object Il n'y a donc jamais d'arguments à sa construction
import java.awt.*;import javax.swing.*;import java.awt.event.*;
La méthode addActionListenerattend un objet qui implémente l'interface ActionListnerpublic class jboutton {
public static void main(String [] args) {JFrame jf = new JFrame();jf setSize(400 100);
l'interface ActionListner :
Possibilité de construire une classe anonyme de ce type.
Contraction pour la créationjf.setSize(400,100);jf.setVisible(true);
JButton plum = new JButton("Appuyez ici");
Contraction pour la créationdirecte d'une classeanonyme (combinaison de la définition et d'une instance)
JButton plum new JButton( Appuyez ici );jf.getContentPane().setLayout(new BorderLayout());jf.getContentPane().add(plum, "East");jf.pack();
Implémente l'interface ActionListner
@iri
sa.f
r
plum.addActionListener( new ActionListener() {public void actionPerformed(ActionEvent e) {
System.out.println("nombre de clic "+ i++);}
nombre de clic 1nombre de clic 2nombre de clic 3
eric
.anq
uetil
@
123
int i=1;} );
}}
fermeture de l'application
AWT► AWT
2 mots sur l’AWT et JFC
AWT : Abstract Window Toolkit (java.awt.*) AWT : Abstract Window Toolkit (java.awt. ) Package (JDK 1.0/1.1) pour la création d’interface
gestion de fenêtre, bouton, etc.
À partir de la version JDK 1 1 : cette librairie a été étendue/remplacée avec À partir de la version JDK 1.1 : cette librairie a été étendue/remplacée avec une librairie plus riche Swing.
JFC (JDK 1 2) J F d ti Cl (j i *) JFC (JDK 1.2) : Java Foundation Classes (javax.swing.*) Nouvelle librairie plus riche pour la gestion d’interface qui intègre :
look and feel, java 2D API (Application Programmer Interface)d d d l t S i drag-and-drop, les composants Swing, …
Les composants Swing (JScrollBar, JButton, JTextField, …) remplacent les composants AWT qui sont plus simples mais plus rudimentaires.composants AWT qui sont plus simples mais plus rudimentaires.
Terminologie : Control : Terme générique (widget sous Unix) définissant les éléments
@iri
sa.f
r
Control : Terme générique (widget sous Unix) définissant les éléments manipulables de l’écran : bouton, scrollbar, Text, Menu, etc.
Container (Conteneur) : fenêtres Windows pouvant contenir un ensemble de Controls ou d’autres Containers
eric
.anq
uetil
@
125
Controls ou d autres Containers
Component (Composant) : nom collectif pour les Containers et Controls
Hiérarchie de composants et conteneurs
Une partie de la hiérarchie de composants et conteneurs Une partie de la hiérarchie de composants et conteneurs
Javax.swingJava.awt Java.applet
Javax.swing.JComponentJava.awt.Component JLabel
JScrollPaneButton
Label
JPanel
JScrollPane
Java.awt.ContainerWindow Frame Javax.swing.JFrame
@iri
sa.f
r
Java.awt.Panel Java.applet.Applet
eric
.anq
uetil
@
126
Exemple 1 : une JFrame
Container : Jframe Fenêtre avec bordure Container : Jframe Fenêtre avec bordure
Une fenêtre d'application est modélisée par l'instance d'une classe dérivant de la classe Frame
La fenêtre va jouer un rôle de conteneur dans lequel on va ajouter des composants (menu, bouton, etc.)
Remarques :
la fenêtre est redimensionnable
la fermeture de la fenêtre est à la charge du concepteur
import javax.swing.*;
public class FrameDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("Exemple1");
@iri
sa.f
r
JFrame frame new JFrame( Exemple1 );
frame.setSize(400,100);
frame.setVisible(true);
eric
.anq
uetil
@
127
}
}
Exemple 2 : Jframe / JLabelContainer : Jframe
public class LabelDemo extends JFrame{
public LabelDemo (String s) {
Fenêtre avec bordure
public LabelDemo (String s) {
super(s);
setSize(400,100);
setVisible(true); Gestionnaire d'agencement :getContentPane().setLayout( new FlowLayout() );
}
bli t ti id i (St i [] ) {
Gestionnaire d agencement :FlowLayout
Méthode de placement des composants d'un container
public static void main(String[] args) {
JFrame frame = new LabelDemo("Exemple2");
JLabel jl1 = new JLabel("Bonjour");
JLabel jl2 = new JLabel(" * ");
Ici : composants ajoutésles uns après les autres, de la gauche vers la droiteJLabel jl2 new JLabel( );
frame.getContentPane().add( jl1 );
frame.getContentPane().add( jl2 );
frame.pack();Ajout de 2 champs "texte" statiques :JLabel
@iri
sa.f
r
}
}
eric
.anq
uetil
@
128
Exemple 3 : Jframe / JPanel
Structuration d'un ensemble d'éléments dans un Jpanel Structuration d un ensemble d éléments dans un Jpanel
Exemple : création d'une barre de boutons
Agencement :JLabel
JButton
Agencement :BorderLayout
les composants sont répartis en 5 zones :
JButton
JPanelNorth, South, West, East, Center
import javax.swing.*;import java.awt.*;
public class Frame2Demo {
import javax.swing.*;import java.awt.*;
public class mesButton extends JPanel { public class Frame2Demo {
public static void main(String[] args) {JFrame maFrame = new JFrame("Exemple3"); maFrame.setSize(400,100);
public class mesButton extends JPanel {
public mesButton(){ this.setBackground(Color.blue);this.add(new JButton ("Bouton1"));
@iri
sa.f
r
a a e se S e( 00, 00);Container c=maFrame.getContentPane();c.setLayout( new BorderLayout() );c.add( new JLabel("JLabel1"),"North");c.add( new mesButton(),"South");
s add( e J utto ( ou o ));this.add(new JButton ("Bouton2"));this.add(new JButton ("Bouton3"));
} }
eric
.anq
uetil
@
129
c.add( new mesButton(), South );maFrame.setVisible(true);
}}
}
Exemple 4 : Jframe / MenuBar
M B
JLabel
MenuMenuBar
MenuItem
JButton
Agencement :GridLayout
les composants sont répartis dans une grille
JPanelrépartis dans une grilledont on définit le nombre de lignes et de colonnes
public class Frame3Demo {public static void main(String[] args) {
JFrame maFrame = new
public class monMenu extends MenuBar {public monMenu(){
JFrame maFrame = new JFrame("Exemple3"); maFrame.setSize(400,100);maFrame.setMenuBar(new monMenu());Container c=maFrame getContentPane();
Menu menu1 = new Menu("Menu1");menu1.add(new MenuItem("menuItem11"));menu1.add(new MenuItem("menuItem12"));menu1.add(new MenuItem("menuItem13"));
@iri
sa.f
r
Container c=maFrame.getContentPane(); c.setLayout( new GridLayout(2,2) );c.add( new JLabel("Jlabel1")); c.add( new JLabel("Jlabel2"));c add(new mesButton());
( ( ))
Menu menu2 = new Menu("Menu2");menu2.add(new MenuItem("menuItem21"));menu2.add(new MenuItem("menuItem22"));
eric
.anq
uetil
@
130
c.add(new mesButton());maFrame.setVisible(true);
} }
this.add(menu1);this.add(menu2);
} }
Principe de la gestion des événements (JDK 1.1 et +)
Le modèle des événements se fonde sur 3 types d'objets Le modèle des événements se fonde sur 3 types d objets Les objets qui sont à la source des événements
Les composants (component) : container, canvas, button, … Les objets qui sont récepteurs d'évènements Les objets qui sont récepteurs d évènements
Les délégués de la gestion des événements (hérite de EventListener). Les objets événements
ActionEvent MouseEvent WindowEvent ActionEvent, MouseEvent, WindowEvent
Source de l’événement
Composant (Component)
Délégué implémente
un EventListenerEnregistrement auprès de la source1
l’é é t
La source prévient le(s) délégué(s) enregistré(s)3
@iri
sa.f
r
l’événement (un objet)
La source déclenche en évènement
Le délégué accède à l'évènement
2 4
eric
.anq
uetil
@
131
en évènement accède à l évènement
Évènements et Interfaces "Listener"
Les événements sont des objets classés par thèmes : Les événements sont des objets classés par thèmes :
<type>Event : java.awt.event.
ComponentEvent
KeyEvent
MouseEvent
WindowEventWindowEvent
…
A chaque classe d’événements est associée une interface (Listener)
définit les méthodes d'écoute associées aux évènements
les objets délégués implémentent ces interfaces
<type>Listener <type>Listener
ComponentListener
KeyListener
@iri
sa.f
r
MouseListener
WindowListener
…
eric
.anq
uetil
@
132
…
Les interfaces "Listener"
Une interface définit les méthodes d'écoute associées Une interface définit les méthodes d écoute associées à chaque type d'évènements
Exemple
interface MouseListener associée à l'événement MouseEvent
<Interface>
MouseListenerType de l'évènement
déclenché
void mouseClicked(MouseEvent)
déclenché
void mousePressed(MouseEvent)
void mouseReleased(MouseEvent)
@iri
sa.f
r
…
Action associée au
eric
.anq
uetil
@
133
déclenchement de l'évènement
Exemple 5 : Évènements et JFrame
Exemple : Gestion de la fermeture de la fenêtre Exemple : Gestion de la fermeture de la fenêtre
Délégué de type WindowListener (interface)
Fenêtre vide (cadre) avec titre : « exemple »
import javax.swing.*;i t j t t *
class MonDelegue implements WindowListener {
WindowListener (interface)p
import java.awt.event.*;
public class Ex1Evt {public static void main (String[] args) {
class MonDelegue implements WindowListener {public void windowClosing(WindowEvent e)
{System.exit(0);}public void windowClosed(WindowEvent e) {}p ( g[] g ) {
JFrame jframe = new JFrame ("exemple");jframe.setSize (400,100);jframe.setVisible(true);
public void windowClosed(WindowEvent e) {}public void windowOpened(WindowEvent e) {}public void windowIconified(WindowEvent e) {}public void windowDeiconified(WindowEvent e) {}
MonDelegue Del=new MonDelegue();jframe.addWindowListener(Del);
}
public void windowDeiconified(WindowEvent e) {}public void windowActivated(WindowEvent e) {}public void windowDeactivated(WindowEvent e) {}
}
@iri
sa.f
r
}}
}
Méthodes d'écoute (de réaction)
eric
.anq
uetil
@
134
Enregistrement du délégué(du Listener)
aux évènements
Utilisation d'un "Listener Adapter"
Pour éviter les contraintes des interfaces "Listener" Pour éviter les contraintes des interfaces Listener
Exemple : on veut uniquement redéfinir une méthode "windowClosing"
Utiliser un ListenerAdapter
C'est une classe abstraite qui implémente les interfaces Listner avec des méthodes vides (non abstraite !)
Exemple : WindowAdapter / WindowListener Exemple : WindowAdapter / WindowListener
Public abstract class WindowAdapter implements WindowListener {
public void windowClosing(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }p ( ) { }
public void windowOpened(WindowEvent e) { }
public void windowIconified(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
@iri
sa.f
r
public void windowDeiconified(WindowEvent e) { }
public void windowActivated(WindowEvent e) { }
public void windowDeactivated(WindowEvent e) { }
eric
.anq
uetil
@
135
}
Exemple 6 : Jframe / Jbutton
import java awt *;import javax swing *;import java awt event *;import java.awt. ;import javax.swing. ;import java.awt.event. ;
public class jboutton {
public static void main(String [] args) {JFrame jf = new JFrame();
nombre de clic 1nombre de clic 2
JFrame jf = new JFrame();jf.setSize(400,100);jf.setVisible(true);
WindowListener l = new WindowAdapter() {
nombre de clic 3fermeture de l'application
WindowListener l = new WindowAdapter() {public void windowClosing(WindowEvent e) {
System.out.println("fermeture de l'application");System.exit(0);
}
Délégation de la gestion desévènements :WindowAdapter
}};jf.addWindowListener(l);
JButton plum = new JButton("Appuyez ici");
Contraction pour la créationdirecte d'une classeanonyme (combinaison de la définition et d'une instance)
JButton plum new JButton( Appuyez ici );jf.getContentPane().setLayout(new BorderLayout());jf.getContentPane().add(plum, "East");jf.pack();
Gestionnaire d'agencement :BorderLayout
@iri
sa.f
r
plum.addActionListener( new ActionListener() {public void actionPerformed(ActionEvent e) {
System.out.println("nombre de clic "+ i++);}
Méthode de placement des composants d'un container
Ici : décomposition du conteneuren 5 zones (North South )
eric
.anq
uetil
@
136
}private int i=1;
} );}}
en 5 zones (North,South, …)
Objets Sources et Objets délégués
Un délégué peut être enregistré auprès de plusieurs sources Un délégué peut être enregistré auprès de plusieurs sources
Enregistrement
Source1
Délégué
Source2
Plusieurs délégués peuvent réagirent à une même source
Délégué1
Enregistrement
@iri
sa.f
r
Source
Délégué2
eric
.anq
uetil
@
137
Délégué2
► Exemple : une application graphique application graphique
basée sur 2 Jpanel(i t d ti TP)(introduction au TP)
Présentation de L’IHM Vers un petit éditeur graphique Vers un petit éditeur graphique
Barre de menu
Figuresdisponibles
Figuresélectionnée
@iri
sa.f
r
Panel d’icônes
Panel de dessin
L f êt hi
eric
.anq
uetil
@
139
La fenêtre graphique
Préambule : les figures géométriques de base
Définition de classes de figures à partir de la classe abstraite Figure Définition de classes de figures à partir de la classe abstraite Figure
@iri
sa.f
rer
ic.a
nque
til@
140
Les figures géométriques de base / Ellipse
Exemple : La classe Ellipse Exemple : La classe Ellipse
Redéfintion de la méthode dessiner
public class Ellipse extends Figure{
/**
* Constructeur
* @param largeur largeur de l'ellipse
* @param hauteur hauteur de l'ellipse
*/
public Ellipse(int largeur, int hauteur){
super(largeur hauteur);super(largeur, hauteur);
}
public void dessiner(Graphics g){
@iri
sa.f
r
( g){
g.setColor(Color.BLACK); // couleur de tracé
g.drawOval(rectangleEnglobant.x, rectangleEnglobant.y,
rectangleEnglobant.width, rectangleEnglobant.height);
eric
.anq
uetil
@
141
}
}
L’Architecture : 1 premier diagramme de Classe
public class PanelIcones extends JPanel{
// liste des figures-icones
public class FenetreGraphique {
// Panel support du dessin des figures
i t P lD i lD i
// liste des figures icones
private Vector listeFigures;
// Figure-icone sélectionnée
private Figure figureSelectionnee;private PanelDessin panelDessin;
//Panel support des icones-figures
private PanelIcones panelIcones;
//
// …
}
public class PanelDessin extends JPanel{
@iri
sa.f
r
//…
}// liste de toutes les figures du Panel de dessin
private Vector listeFigures;
// Liste des figures sélectionnées
private Vector listeFiguresSelectionnees;
eric
.anq
uetil
@
142
private Vector listeFiguresSelectionnees;
// …
}
public class PanelIcones extends JPanel{
// Côté d'un icone
Le Panel des Icones / Constructeur
private static final int COTE_CASE = 100;
// ordonnée du centre du prochain icone ajouté
private int yCourant; Figuresdi ibl// liste des figures-icones
private Vector listeFigures;
// Figure-icone sélectionnée
private Figure figureSelectionnee;
gdisponibles
Figureprivate Figure figureSelectionnee;
public PanelIcones(){
setBackground(Color.LIGHT_GRAY); // fond du panel
listeFigures = new Vector(); // initialisation de la liste des figures-icones
Figuresélectionnée
g () g
// définition de la taille de référence du Panel (associé à la notion de pack())
setPreferredSize(new Dimension(COTE_CASE, 3*COTE_CASE));
// ajout des iconesPanel
d’icônes
yCourant=COTE_CASE/2;
ajouter(new Cercle(40)); // Cercle, Ellipse, … figures graphiques
ajouter(new Ellipse(40, 20)); // la méthode ajouter gère l’ajout dans la liste
ajouter(new Carre(50)); // et la mise jour du décalage (yCourant)
@iri
sa.f
r
ajouter(new Carre(50)); // et la mise jour du décalage (yCourant)
// figure sélectionnée par défaut
figureSelectionnee = (Figure)listeFigures.get(0);
// i ti d’ délé é é l é è t l P lI
eric
.anq
uetil
@
143
// association d’un délégué pour gérer les évènements sur le PanelIcone
addMouseListener(new DelegueIcones());
}
Le Panel des Icones / Paint
La méthode paint(Graphics g) La méthode paint(Graphics g)
est appelée à chaque fois que la fenêtre à besoin d'être redessinée (g représente alors le bon contexte graphique
i d i )
public class PanelIcones extends JPanel{
// Dessin du Panel
pour pouvoir dessiner …)
// Dessin du Panel
public void paint(Graphics g){
super.paint(g); // pour effacer le fond (nécéssaire pour les Jpanel)
// dessin d’un cadre noir
g.setColor(Color.BLACK);
g.drawRect(getX(), getY(), getWidth()-1, listeFigures.size()*COTE_CASE-1);
// dessin des 3 icones
f (i i 0 i li Fi i () i ){for(int i=0; i<listeFigures.size(); i++){
Figure f = (Figure)listeFigures.get(i);
f.dessiner(g);
if(f==figureSelectionnee) //l’icone sélectionnée est entourée en rouge
@iri
sa.f
r
if(f figureSelectionnee) //l icone sélectionnée est entourée en rouge
f.dessinerRectangleSelection(g);
}
}
eric
.anq
uetil
@
144
// Retourne la figure sélectionnée
public Figure retourneFigureSelectionnee(){ return figureSelectionnee; }
}
Le Panel des Icones / Gestion des évènements
La classe interne privée déléguée : DelegueIcones La classe interne privée déléguée : DelegueIcones
Enregistrée dans le Main au près de PanelIcone
Met à jour de l’icône sélectionnée dans le PanelIcone
// Classe déléguée pour les événements souris
private class DelegueIcones extends MouseAdapter {
en fonction des clics souris
p g p {
/**
* Fonction appelée lors d'un clic souris
* Sélectionne la figure cliquée
*/
public void mousePressed(MouseEvent e){
Boolean stop=false;
for(int i=0; i<listeFigures size()&&!stop; i++){for(int i=0; i<listeFigures.size()&&!stop; i++){
Figure f = (Figure)listeFigures.get(i);
if(f.contient(e.getX(), e.getY())){
figureSelectionnee = f;
@iri
sa.f
r
g
stop=true;
}
}
eric
.anq
uetil
@
145
repaint(); // demande un rafraichissement de l’écran => appel indirect au Paint
}
}
IHM : ce qu’il reste à faire
Il reste à faire : Il reste à faire :
Le Panel Dessin : où l’on va dessiner les figures
La fenêtré graphique qui va contenir
Menu Panel Dessin Panel Icone Menu, Panel Dessin, Panel Icone
La gestion des évènements sur le Panel Dessin: la classe DelegueMouse
gère les clics souris au niveau du panel de dessin :
j t li d lib d l d d i d’ fi d t d ajout, par un clic dans une zone libre du panel de dessin, d’une figure du type de celle sélectionnée dans le panel d’icônes,
sélection/désélection d’une figure déjà présente dans le panel de dessin par un clic sur cette figure ;sur cette figure ;
cette classe doit contenir une référence vers le panel de dessin pour pouvoir agir sur ses figures, ainsi qu’une référence vers le panel des icônes pour récupérer la figure à ajouter.ajouter.
La gestion des évènements sur le Menu : la classe DelegueMenuItems
gère la sélection des items « supprimer » et « aligner » :
« supprimer » : suppression des figures sélectionnées du panel de dessin
@iri
sa.f
r
« supprimer » : suppression des figures sélectionnées du panel de dessin,
« aligner » : alignement selon l’axe vertical des figures sélectionnées du panel de dessin.
cette classe doit contenir une référence vers le panel de dessin pour pouvoir agir sur ses
eric
.anq
uetil
@
146
cette classe doit contenir une référence vers le panel de dessin pour pouvoir agir sur ses figures.
L’Architecture : diagramme de Classe avec gestion des evts
@iri
sa.f
rer
ic.a
nque
til@
147
► Introduction aux ► Introduction aux Applets
« Applet » : utilisation d’un framework simple
Programme de type Applet Programme de type Applet programme Java destiné à fonctionner via un navigateur Web
Sécurité ne peut pas accéder au système de fichier local (sauf applet signées)
Développement basé sur le package java.applet : un framework très simple le programmeur va - dériver certaines classes de base ;
- surcharger certaines fonctionnalités ; - écrire ses fonctions spécifiques.
l l A l t èd d éth d i () la classe Applet ne possède pas de méthode main()
Méthodes pour la manipulation d’une Applet (classe Applet)i it() init() : est appelée au 1er chargement de l’Applet en mémoire :
pour initialiser les structures de données de l'Applet start() : est appelée à chaque entrée dans la page Web
(pour les animations, ...)
@iri
sa.f
r
(pour les animations, ...)
stop() : est appelée quand on va quitter l'Applet paint(Graphics g) : est appelée à chaque fois que la fenêtre à besoin
d'être redessinée (g représente alors le bon contexte
eric
.anq
uetil
@
149
d être redessinée (g représente alors le bon contexte graphique pour pouvoir dessiner …)
« Applet » : chargement d'une Applet
Demande de chargement d'une pageassociée à une Applet
1
Navigateur Web
Chargement de la page HTML
(C )2
Client Serveur
(CloudApplet.html)
Possédant un
navigateur Web
avec JVM
Qui va fournir
l'AppletDemande de chargement de l'Appletde l Appletinvoquée dans la page
Chargement du byte-code
3
@iri
sa.f
r
g y
de l'Applet
(.class)
Exécution de l'Applet avec
4
eric
.anq
uetil
@
150
Exécution de l Applet avecla JVM du navigateur du client
« Applet » : démonstration
Réaction aux clics souris
Demo.htlm
Réaction aux clics souris
Création d'un point
Calcul de la droite de régression
Gestion de l'affichage
@iri
sa.f
rer
ic.a
nque
til@
151
import java.applet.*; import java.awt.event.*; import java.awt.*; import java.util.*;
« Applet » : un exemple / codeDemo.htlm
public class CloudApplet extends Applet implements MouseListener {
private Vector _points = new Vector();
public void init() {
addMouseListener(this);
Version compactée où la source (Component ici l’applet) est
i l délé é (M Li t )addMouseListener(this);
}
public void mousePressed(final MouseEvent e)
{ _points.addElement(new Point(e.getX(), e.getY()));
aussi le délégué (MouseListener)
{ _p ( ( g () g ()))
repaint();
}public void mouseReleased (final MouseEvent p1) { } public void mouseEntered (final MouseEvent p1) { }
Gestion des événements
public void mouseEntered (final MouseEvent p1) { }// …
public void paint(Graphics g)
{ for (int i = 0; i < _points.size(); i++)
{ Point p = (Point)_points.elementAt(i);
g.drawOval(p.x - 2, p.y - 2, 5, 5);
}
@iri
sa.f
r
}
if (regression())
{ int xright = getSize().width;
g drawLine(0 (int)b xright (int) (m * xright + b)); }
eric
.anq
uetil
@
152
g.drawLine(0, (int)b, xright, (int) (m xright + b)); } }private boolean regression() {…};
}
« Applet » : invocation de l'Applet / html
Création d'un Fichier HTML pour invoquer l’Applet Création d un Fichier HTML pour invoquer l Applet
Utilisation de l’appletviewer ou un browser Web pour exécuter l'Applet
Exemple basic : attention plus compliqué avec les Japplet ….
Cf. versions 1.2 de Java /plugins / IE / Netscape …
Cf http://java sun com/products/plugin/1 2/docs/tags html Cf. http://java.sun.com/products/plugin/1.2/docs/tags.html
<HTML>CloudApplet.html
<HEAD>
<TITLE> Applet HTML Page </TITLE>
</HEAD>
C oud pp et t
<BODY>
<h1> CloudApplet </h1>
@iri
sa.f
r
<APPLET code="CloudApplet.class" width=350 height=200> </APPLET>
<hr>
</BODY>
eric
.anq
uetil
@
153
</BODY>
</HTML>
« Applet » : action du paintimport java.applet.*;import java.awt.event.*;import java.awt.*;import java.util.*;
bli l Cl dA l t t d A l t i l t M Li t {public class CloudApplet extends Applet implements MouseListener { static int decal=1; // pour observer les appels a paintprivate Vector _points = new Vector(); private double m; private double b;
bli id i it() {
Demo.htlm
public void init() {addMouseListener(this);decal=1;
}public void paint(Graphics g) {
Exemple de mise en évidence des mécanismes sous tendus par le f k
public void paint(Graphics g) { for (int i = 0; i < _points.size(); i++) { Point p = (Point)_points.elementAt(i);g.drawOval(p.x - 2, p.y - 2, 5, 5);
}
framework :
Exemple : Gestion automatique du rafraîchissement / décalage de la d it à h l d l
}decal+=1;if (regression()) {
int xright = getSize().width;g.drawLine(0+decal, (int)b, xright, (int) (m * xright + b));
}
droite à chaque appel de la méthode paint.
g ( , ( ) , g , ( ) ( g ));}
}private boolean regression() { … }
public void mousePressed(final MouseEvent e) { _i t ddEl t( P i t( tX() tY()))
@iri
sa.f
r
points.addElement(new Point(e.getX(), e.getY()));repaint();
}public void mouseReleased(final MouseEvent p1) { } public void mouseEntered(final MouseEvent p1) { }
eric
.anq
uetil
@
154
public void mouseEntered(final MouseEvent p1) { }public void mouseClicked(final MouseEvent p1) { } public void mouseExited(final MouseEvent p1) { }
}
► Introduction aux ► Introduction aux Generics
Les Generics – Introduction
ObjectifsObjectifs
Possibilité d’abstraire des types (on parle de types paramétrés)
Exemple d’utilisation : invocation de types paramétrés
Amélioration de la lisibilité et de la robustesse
// avant java 5List l1 = new ArrayList(); // liste d'Objectl1.add(new Integer(0)); // ajout d'un Integer qui est un Object( g ( )) j g jInteger x = (Integer) l1.iterator().next(); // nécessité d'un cast : Object -> Intergerl1.add(new Character('a')); // Possible !?: ajout d'un Character qui est un Object
// apres java 5List<Integer> l2 = new ArrayList<Integer>();// Liste d'Integer (le type de la liste a été spécifié : <Integer>)l2.add(new Integer(0)); // ajout d'un Integer à une liste d'Integer : OK!Integer x2 = l2 iterator() next();
@iri
sa.f
r
Integer x2 = l2.iterator().next();// Plus besoin de Cast ! On est certain du type des éléments de la liste
l2.add(new Character('a')); // Maintenant ImPossible : vérification de type statique : à la compilation
eric
.anq
uetil
@
156
// Maintenant ImPossible : vérification de type statique : à la compilation// Maintenant =>The method add(Integer) in the type List<Integer> // is not applicable for the arguments (Character)
Les Generics – Définition de “generics”
On spécifie à la déclaration du « Generics » (classe paramétrée)On spécifie à la déclaration du « Generics » (classe paramétrée)les paramètres formels entre <>
bli i f Li E { // E è f l d l'i f Lipublic interface List<E> { // E = paramètre formel de l'interface Listvoid add(E x);Iterator<E> iterator();
}}public interface Iterator<E> { // E = paramètre formel de l'interface Iterator
E next();boolean hasNext();
}
Principe des « Generics »
}
Invocation d’une liste d’entier : List<Interger>
<=> Attention oui et NONpublic interface IntegerList {
@iri
sa.f
r
< > Attention oui et NONvoid add(Integer x)Iterator<Integer> iterator();
}
eric
.anq
uetil
@
157
Pas de duplication du code pour chaque type de paramètre utilisé
Les Generics – Définition de “generics”
Le « Generic » est compilé en une unique classeLe « Generic » est compilé en une unique classe
Les paramètres formels sont remplacés à l’invocation du « Generic » par les paramètres effectifs
List<String> ls = new ArrayList<String>();List<Integer> li = new ArrayList<Integer>();List Integer li new ArrayList Integer ();
System.out.println(ls.getClass() == li.getClass());System.out.println(ls.getClass().getName());System.out.println(li.getClass().getName());
=> réponse
@iri
sa.f
r
truejava.util.ArrayListj til A Li t
eric
.anq
uetil
@
158
java.util.ArrayList
Les Generics – Héritage
Héritage et genericsHéritage et generics
Si CD hérite de CBAlors
Cl G<CD> ’hé it PAS d Cl G<CB>ClassG<CD> n’hérite PAS de ClasseG<CB>
List<String> ls = new ArrayList<String>();Li Obj l l // T i h f Li S i Li Obj
Pourquoi ? Si c’était possible : ls et lo référenceraient la même liste !
List<Object> lo = ls; // Type mismatch: cannot convert from List<String> to List<Object>
Pourquoi ? Si c’était possible : ls et lo référenceraient la même liste !
donc
lo.add(new Object());
String s = ls.get(0); // Pb on essaie d’assigner un objet à une string !
@iri
sa.f
r
=> ls pourrait contenir des objets n’étant pas des String !
eric
.anq
uetil
@
159
Les Generics – Wildcards et Bounded Wildcards Utilisation du wildcard <?>
class Fenetre{ public void draw(Figure s) { s.draw(this); } Rectangle Cercle
public void drawAll(List<Figure> Figures) { for (Figure s: Figures) { s.draw(this); }
} // on ne peut passer en paramètre que des List<Figure> Figure
public void drawAll1(List<?> Figures) { // wildcardsfor (Figure s: (List<Figure>)Figures) { s.draw(this); } // Cast … dangereux !
} // on peut passer en paramètre des List<de n’importe quel objet>} p p p p q j
public void drawAll2(List<? extends Figure> Figures) { // Bounded Wildcardsfor (Figure s: Figures) { s.draw(this); } // ok
} // on peut passer en paramètre des List< Objet héritant de Figure>} // on peut passer en paramètre des List< Objet héritant de Figure>
public static void main(String[] args) {Fenetre ca=new Fenetre();
@iri
sa.f
r
ca.draw(new Cercle());ca.drawAll(new ArrayList<Cercle>()); // The method drawAll(List<Figure>) in the type Canvas
// is not applicable for the arguments (ArrayList<Cercle>)ca.drawAll1(new ArrayList<Cercle>()); // ok
eric
.anq
uetil
@
160
( y ());ca.drawAll2(new ArrayList<Cercle>()); // ok
}}
Les méthodes Generic
Recopie d’éléments d’une liste à l’autre
Rectangle Cercle
Recopie d éléments d une liste à l autre
public static void recopie( List<? extends Rectangle> Figures,List<Rectangle> Rectangles) {
Figure
List<Rectangle> Rectangles) { for (Rectangle r: Figures) { Rectangles.add(r); }
}
Comment généraliser ?
public static void recopie1(List<?> l1, List<?> l2) { for (Object r: l1) { l2 add(r); } // Erreur à la compilation !
Utilisation d’une méthode générique
for (Object r: l1) { l2.add(r); } // Erreur à la compilation !}
public static <T> void recopie2(List<? extends T> l1, List<T> l2) { for (T r: l1) { l2.add(r); } // ok !
}
@iri
sa.f
r
}
public static <T,S extends T> void recopie3(List<S> l1, List<T> l2) { for (T r: l1) { l2.add(r); } // ok : mais préférer la solution précédente
}
eric
.anq
uetil
@
161 Préférer l’utilisation des Wildcards : solution + concise et + claire !
}
► Quelques ► Quelques remarques
Quelques Remarques 1/2 ....
Passer par une bonne analyse des concepts associés au problème avant toute Passer par une bonne analyse des concepts associés au problème avant toute
implémentation
analyse et conception objet, gestion de projet de type spirale,...analyse et conception objet, gestion de projet de type spirale,...
Chaque classe doit représenter un concept compact et bien définiq p p p
éviter les objets trop gros, avec trop de méthodes,...
utiliser les mécanismes objets simples,...j p
Tester et Valider de manière unitaire vos objets
faire des main() pour chaque classe
des exemples d'utilisation
@iri
sa.f
r
Penser aux éléments essentiels d'une classe "type"
eric
.anq
uetil
@
163
equals,...
constructeur par recopie,...
Quelques Remarques 2/2....
Agrégation à héritageAgrégation à héritage
l'agrégation est bien souvent la meilleure option pour réutiliser des concepts
limiter l'héritage pour des modélisations adaptées
penser à la notion d'interface : simple, puissante et utile !
Respecter une convention de notation pour le nommage des variables
UneClasse uneMethode // en Java
A la conception d'une classe penser à l'utilisateur et à la maintenance
encapsuler, protéger, commenter,...
offrir une gestion complète des erreurs: exceptions,...
@iri
sa.f
r
Documenter vos programmes, concepts, analyses
eric
.anq
uetil
@
164
Doc++, javadoc,...
A► Annexes
► Java 5 ► Java 5 Tiger les petits plus
Introduction : Java5 (Tiger)
Automne 2004Automne 2004
Révision de Java : Java 5 (nom de code Tiger) : J2SE 5.0
Les Principales évolutions
Autoboxing et Auto-Unboxing des types Primitifs
Les itérations sur des collections Les itérations sur des collections
Type énuméré : enum
Nombre d’arguments variable pour une méthode
Les imports statiques
Les Generics – introduction
les Annotations Supervison de la JVM Synchronisation Client lourd … les Annotations, Supervison de la JVM, Synchronisation, Client lourd
Intégration avec Eclipse
@iri
sa.f
r
Nécessité de passer à la version Eclipse 3.1 pour exploiter les nouvelles fonctionnalités de Java5
Preferences>java>compiler>Compiler compliance level : 5.0
eric
.anq
uetil
@
167
j p p p
Autoboxing et Auto-Unboxing des types primitifs
Simplification du passage (Type Primitifs / objet)Simplification du passage (Type Primitifs / objet)
boolean/Boolean, byte/Byte, double/Double, short/Short, int/Interger, long/Long, float/Float, char/Character
Exemple
Vector tabDyn=new Vector();// avant Java 5// avant Java 5Character oCar = new Character('a'); // Objetchar car=oCar.charValue(); // unBoxing -> type primitiftabDyn.addElement(new Character(car)); // boxing -> ObjettabDyn.addElement(new Character(car)); // boxing > Objet
// maintenant avec Java 5Character oCar2 = new Character('a'); // objetchar car2=oCar2; // autoUnBoxing// maintenant ok
@iri
sa.f
r
// avant => Type mismatch: cannot convert from Character to chartabDyn.addElement(car2); // autoBoxing// maintenant ok// t Th th d ddEl t(Obj t) i th t V t
eric
.anq
uetil
@
168
// avant => The method addElement(Object) in the type Vector // is not applicable for the arguments (char)
Itérations sur des collections : nouvelle boucle for
Evolution du for pour l’itération sur des collectionsEvolution du for pour l itération sur des collections
For (paramètre formel : Objet Iterable) { corps }
Notation plus légère et concise
List Figures=new ArrayList();Figures.add(new Rectangle());
//...// avant java5for (Iterator i = Figures iterator(); i hasNext(); ) {for (Iterator i = Figures.iterator(); i.hasNext(); ) {
((Figure)i.next()).draw(ca);}
// avec Java 5for (Object s: Figures) {
((Figure)s).draw(ca);
@iri
sa.f
r
NB: On ne peut pas modifier la collection avec cette notation
}
eric
.anq
uetil
@
169
p p
Type énuméré : enum
Avant Java 5 : utilisation de constante de type int Avant Java 5 : utilisation de constante de type int
public class Etapes {public static final int ETAPE0=0;public static final int ETAPE0=0;public static final int ETAPE1=1;public static final int ETAPE2=2;//...//...
}
int e=Etapes.ETAPE1;
Avec Java5 : la construction des enum est type safe
System.out.println(e); // affichage : 1e=10; // possible ! Danger !
Avec Java5 : la construction des enum est type-safe
public enum EtapesJava5 { ETAPE0, ETAPE1, ETAPE2 };
@iri
sa.f
r
EtapesJava5 e2=EtapesJava5.ETAPE0;System.out.println(e2); // affichage : ETAPE0e2=10; // erreur (type-safe)Type mismatch:
eric
.anq
uetil
@
170D’autres raffinements sont encore possibles …
// cannot convert from int to Canvas.EtapesJava5
Nombre d’arguments variable pour une méthode
Notation : « Type »Notation : « Type … »
static void argTest(String ... args) { // nombre variable d’arguments de type Stringfor (String o : args) {( g g ) {
System.out.println(o);}
}
// …
Résultat
argTest("arg1","arg2","arg3"); // 3 paramètresargTest("bonjour","monsieur"); // 2 Paramètres
Résultat
arg1
@iri
sa.f
r
arg1arg2arg3bonjour
eric
.anq
uetil
@
171
bonjourmonsieur
Printf : Sortie standard formatée
Similaire à la fonction « C » printf !Similaire à la fonction « C » printf !
float d1=1.1f;float d2=2f;float d2=2f;
System.out.printf("d1= %f et d2= %1.2f \n", d1,d2);
Résultat
d1 1 100000 t d2 2 00
Formatage avancé
d1= 1,100000 et d2= 2,00
Formatage avancé
Cf. java.util.Formatter
@iri
sa.f
rer
ic.a
nque
til@
172
Le scanner : entrée formatée
Sur l’entrée standard / Méthode next : blocante !Sur l entrée standard / Méthode next : blocante !
Scanner s= new Scanner(System.in);String entreString=s.next();
< maChaine< 2005> entreString= maChaine et entreInt= 2005int entreInt=s.nextInt();
System.out.printf("entreString= %s et entreInt= %d \n",entreString,entreInt);s.close();
> entreString= maChaine et entreInt= 2005
Sur un fichier Scanner sc = null;
try { sc = new Scanner(new File("sequence_ordres"));}
catch (java.io.FileNotFoundException e) { System.out.println(e); }
while (sc.hasNextInt()) { // est-ce qu’il y a un nouvel élt (token) à analyser ?
System.out.println(sc.nextInt()); // on récupère l’élt suivant (token)
}
Définition de délimiteurs // StringTokenizer
}
@iri
sa.f
r
String entree="s-a-l-u-t";Scanner s2= new Scanner(entree).useDelimiter("\\s*-\\s*");String sortie = s2.next() + s2.next()+ s2.next()+ s2.next()+ s2.next();
eric
.anq
uetil
@
173
g () () () () ();s2.close();System.out.printf(sortie); salut
Les imports statiques
ObjectifsObjectifs
Rendre visible des méthodes et variables statiques
// Avant
getContentPane().add(plum, BorderLayout.CENTER);
// Avec Java5 et les imports statiques
Import static java.awt.BorderLayout.*getContentPane().add(plum, CENTER);
Attention aux conflits de nommageAttention aux conflits de nommage
@iri
sa.f
rer
ic.a
nque
til@
174