Les concepts de la Programmation Orientée Objet en Java Prawee Sriplakich

publicité
Les concepts de la
Programmation Orientée
Objet en Java
Prawee Sriplakich
[email protected]
Ce support de cours est disponible sur
http://www-src.lip6.fr/homepages/Prawee.Sriplakich/
mise a jour : 18/09/2006
1
Organisation
1. Introduction à la technologie Java
2. Concepts POO (basiques)
3. Environnements de Développement en Java.
4h
4. Concepts POO (avancés)
8h
5. Tableaux, collections et Map
6h
6. Manipulation des entrées/sorties
6h
7. Threads et synchronisation
6h
8. Manipulation des documents XML avec Java
6h
2
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Evaluation
50% Contrôle continu
Les TPs suivants seront évalués :
Travail en binôme
Les critères d’évaluation sont :
4.3 : Réalisation des interfaces du mécanisme d'événements
6.1 : Flux de données et sérialisation
8.2 : Sérialisation et désétatisation d’objets en XML avec DOM
L’explication sur le lancement du programme.
La correction du programme.
Le scénario de test couvrant toutes les fonctionnalités du
programme
La lisibilité du code et le commentaire sur le code.
Le Java Doc et le document expliquant l’architecture globale du
programme.
50% Examen (2h)
Les documents du cours et des notes personnelles sont
autorisés.
3
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
1. Introduction à la
technologie « Java »
Java et une plateforme
d'entreprise
4
Qu’est ce que « Java » ?
Un langage de programmation interprété et
compilé.
Java code Byte code
Byte code est interprété par JVM
(Java Virtual Machine)
Les applications Java s'exécutent sur quel type de
machines ?
Tous les types de matériels disposant d'une JVM
5
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Comment cela fonctionne t-il ?
La JVM fournit un environnement d'exécution homogène
(malgré l'hétérogénéité des OS/ matériels)
6
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Le « Java Development Kit »
Java est un langage de programmation.
Le « Java Development Kit » est une boite à outils :
un compilateur java
une machine virtuelle « JVM »
un ensemble de bibliothèques (API) pour faciliter la
programmation.
Ex. Gestion d'E/S (ficher, réseaux), les collections (liste, ensemble)
, IHM …
7
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Applets et applications
Deux types de développements sont possibles :
les Applets
Un programme s'exécutant au sein d'un navigateur web.
Téléchargeable en même temps qu'une page web
Pas besoin d'installation
Fonctionnalité limité (par mesure de sécurité)
les applications
Un programme standard s'exécutant sur la JVM.
Moins de restriction (Les utilisateurs doivent faire confiance
avant de l'exécuter)
8
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
La plate-forme entreprise « java »
• Un grand nombre de bibliothèques ont été développées autour du
langage Java
• Elles offrent des fonctionnalités communes des applications
d'entreprises
Ex. Gestion de web, de base de données, de transactions etc.
Simplicité du développement des applications complexes
• La
plateforme concurrence : .NET
9
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
2. Concepts POO
(basiques)
Contenu:
Class, Objet, Instanciation, Attribut, Méthode,
Message (Invocation), Cycle de vie d'objets,
Constructeur, Package
10
Class et objet
Objet
représente une entité dans le monde réel
ou un élément du programme.
Possède des états et des comportements
Ex. un objet "Télévision"
ses états =
{ allumé/éteint, chaîne courante, volume de son },
ses comportements =
{ allumer, changer de chaîne, changer de volume de son,
éteindre }
Class
Un objet est une instance d'une classe la classe
décrit l'objet.
Description des états des attributs de la classe
Description des comportements des méthodes de la
classe.
11
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'une class
public class Television {
// Etat
private int volume;
private int chaine;
private boolean estAllume;
// Comportements
public void allumer() { … }
public void eteindre() { … }
public void augmenterVolume() { … }
public void reduireVolume() { … }
public void changerChaine(int _chaine) { … }
}
NB. Par convention, les noms des classes commencent par majuscule
ceux des attributs/ méthodes commence par minuscule
12
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Instanciation
Une classe peut être réutilisée pour instancier
plusieurs objets
Class
Television
boolean estAllume
int volume
int chaine
Objets
estAllume: true
volume: 5
chaine: 1
estAllume: true
volume: 6
chaine: 2
estAllume: false
volume: 0
chaine: 0
13
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Question
Définir une classe représentant des voitures.
Les états des objets voiture doivent décrire
Démarré ou non, position de boite de vitesse, vitesse…
niveau d'essence, …
Les comportements d'une voiture incluent:
Démarrer, arrêter
Changer boite de vitesse
Accélérer, ralentir
Tourner (selon le dégré spécifié)
14
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Solution
public class voiture {
private boolean estDemarre;
private int posBoiteVitesse;
private int vitesse;
private int niveauEssence;
public void demarrer() { … }
public void arreter() { … }
public void setPosBoiteVitesse(int pos) { … }
public void accelerer() { … }
public void ralentir() { … }
public void tourner(int degre) { … }
}
15
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Le typage d'attributs (et variables)
Un attribut peut être typé :
par une classe
(Sa valeur est donc une référence vers un objet instance de
cette classe)
par un type primitif:
Par un tableau de type primitif, ou de type classe
boolean,
short, int, long,
float, double
byte, char.
Ex. int[] att1; Television[] att2;
Un array est un objet
NB. Une chaine de caractères est un objet instance de la class
String
16
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Méthodes
Le corps d'une méthode contient des instructions
comme la programmation classique.
Il peut accéder aux attributs de la classe
Ex.
public void changerChaine(int _chaine) {
if(_chaine<0 || _chaine>108) {
System.out.println("chaîne invalide ");
} else {
chaine = _chaine; // Accès à l'attribut chaine }
}
17
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Attribut "this"
Lorsque des variables locales portent les mêmes noms
que les attributs de la classe, vous devez utiliser l'attribut
"this" pour les distinguer.
Ex.
public void changerChaine(int chaine) {
if(chaine<0 || chaine>108) {
System.out.println("chaîne invalide ");
} else {
this.chaine = chaine;
// this.chaine signifie l'attribut de la classe
}
}
18
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interaction entre objets: messages
Lors qu'un programme s'exécute, il comporte d'un
ensemble d'objets et ces objets échangent des
messages.
Echange de messages = invocation d'une
méthode
Les paramètres sont envoyé dans le message.
un telecommande
une television
changerDeChaine(3)
19
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interaction entre objets :
via référence entre objets
Afin qu'un objet A puisse invoquer une
méthode de l'objet B, A doit avoir une
référence vers B.
Ex.
public class Telecommande {
Television t; // une référence (un attribut)
…….
public void boutonChaineAppuye(int boutonNo) {
t.changerChaine(boutonNo);
// invocation
}
}
20
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Question
Définir une classe Messenger
objet Messenger représente une
messagerie d'un utilisateur.
Il porte un identifiant, celui de
l'utilisateur
Il référence des objets Messenger
auxquels il peut envoyer un
message.
On peut lui ajouter un contact.
Il accepte un texte de l'utilisateur et
le diffuse aux autres.
Lors de la réception du texte diffusé,
il l'affiche sur l'écran
julien
Un
julie
pierre
21
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Solution
import java.util.Vector;
public class Messenger {
private String idUtilisateur;
private Vector<Messenger> contacts = new
Vector<Messenger>();
public void ajouterContact(Messenger contact) {
contacts.add(contact)
}
public void diffuser(String texte) {
for(int i=0; i< contacts.size(); i++) {
Messenger contact = contacts.get(i);
contact.recevoir(texte);
}
}
public void recevoir(String texte) {
System.out.println(idUtilisateur + " recoit: " + texte);
}
}
22
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Comment commencer le programme:
Méthode main
Un programme Java = un ensemble de classes.
Une méthode main doit être définie dans une
des classes.
Elle doit avoir la signature:
public
static void main(String[] args)
Le tableau <<args>> contient des paramètres passés
par la commande d'exécution d'application
Ex. java MyAppli p1 p2 p3
args est donc {"p1", "p2", "p3"}
23
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Un exemple de la classe main
public class ClasseMain {
public static void main(String[] args) {
// creation d'objets
Voiture v = new Voiture();
Personne p = new Personne();
// déclancher interaction entre objets
p.conduire(v);
}
}
En général, la méthode main sert à:
Configurer le programme:
(créer des objets initiaux du programme)
Déclencher l'interaction entre ces objets
24
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Cycle de vie d'objets : création
Pendant l'exécution du programme, les objets peuvent
être crées et détruits de manière dynamique.
La création d'un objet se fait par l'opérateur new suivi
par le nom d'une classe
Ex new Voiture()
Voiture() est en effet une méthode spéciale, appelée le
"constructeur de la classe".
Le constructeur peut avoir des paramètres permettant de
spécifier l'état initial de l'objet
Ex. new File("document1.doc")
// créer un objet représentant un ficher "document.doc".
25
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'un constructeur
public class Messenger {
private String idUtilisateur;
…
public Messenger(String _idUtilisateur) {
idUtilisateur = _idUtilisateur;
}
…….
}
26
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Cycle de vie d'objets : objets en cours
d'utilisation
L'objet en cours d'utilisation doit être référencé par une
variable et un attribut. (sinon on ne pourrait pas l'utiliser
!!)
Un objet peut être référencé par plusieurs variables
Ex. Voiture v = new Voiture();
// L'objet créé est référencé par la variable v.
Ex. Voiture v1 = new Voiture();
Voiture v2 = v1;
// v1 et v2 référencent le même objet.
Pour utiliser l'objet, on invoque les méthodes de l'objet
Ex. v1.demarrer();
// <<v2.demarrer()>> donnera le même effet car elle référence le
même objet
27
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Cycle de vie d'objets : destruction
Les objets non référencés sont
automatiquement détruits
Ex1.
Voiture v = new Voiture();
v = null;
// v ne référence plus l'objet, donc il sera détruit
Ex2.
public void m() {
Voiture v = new Voiture();
}
// v n'existe pas en dehors de la méthode, donc l'objet sera
détruit à la fin d’exécution de la méthode
28
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Question
L'objet référencé par v sera-il détruit à la fin
exécution de m() ?
public class VoitureManager {
Voiture[] voitures = new Voiture[10];
…..
public void m() {
Voiture v = new Voiture();
voitures[3] = v;
v = null;
}
}
29
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Question
Reprendre l'application Messenger, écrire
la méthode main (dans une classe Main)
servant à commencer le programme.
La méthode main doit configurer 3 objets
Messenger (pour Pierre, Julie, Julien)
avec les liens entre eux.
Elle déclenche l'application en demandant
à Pierre de diffuser un texte.
30
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Solution
public class Main {
public static void main(String[] args) {
Messenger pierre = new Messenger("pierre");
Messenger julie = new Messenger("julie");
Messenger julien = new Messenger("julien");
pierre.ajouterContact(julie);
pierre.ajouterContact(julien);
…. // similaire pour julie et julien
pierre.diffuser("réunion demain à 10h");
}
}
31
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Organisation d'application: package
Une application peut contenir un grand nombre de classes.
Hiérarchie de packages:
Un package permet de grouper un ensemble de classes représentant
un module d'application
modularité
Un package peut contenir non seulement des classes mais également
des sous packages
Ex. mon_appli.ihm.client est une hiérarchie de 3 packages
Espace de nommage
Differents packages peuvent avoir chacun une classe portant le même
nom.
Ex. La classe "Client" du package "com.ibm" est différente de la classe
"Client" du package "com.microsoft"
com.ibm.Client vs. com.microsoft.Client
Eviter le conflit de noms lors de l'intégration de plusieurs modules
d'une application.
32
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Organisation des classes dans les packages
Chacune des
classes est un
fichier.
Les fichiers
doivent être
placés dans le
bon répertoire
selon le package
Dans chaque
classe, on
déclare le
package au
début du fichier
Mot clé:
package
Ex. La classe ProductBrowser est dans le package mon_appli.ihm.client
33
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Spécification de classes dans les autres
packages
Dans le code d'une classe, une autre classe dans un autre package
peut être spécifié avec la forme p1.p2….NomClass
Cette forme est appelée <<nom qualifié>> d'une classe
Ex.
package mon_appli.ihm.client;
public class ProductBrowser {
mon_appli.bd.ProductSearcher ps;
….
}
34
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Spécification de classes dans les autres
packages avec <<import>>
On peut éviter de répéter le nom qualifié plusieurs fois grâce à la
déclaration <<import>>
On peut importer une seule classe d'un package ou toutes ses
classes
Ex. : importer toutes les classes dans le package mon_appli.bd.
package mon_appli.ihm.client;
import mon_appli.bd.*;
public class ProductBrowser {
ProductSearcher ps;
ProductSearcher ps2;
….
}
35
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
3. Environnements de
Développement en Java
Contenu:
IDE, Complication, Exécution, Débuggage,
Génération de documentation, Déploiement
36
Environnement classique et IDE
Deux façons de développer:
Environnement classique
Complication/ execution par ligne de
commande
javac *.java : compiler des fichiers Java.
java [nom de la classe main] : exécuter
l'application
IDE (Integrated Development Environment)
Facilités
Complication automatique
Soulignements d'erreurs syntaxiques
Débuggage avec interface graphique
Ex. Eclipse
37
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Utilisation d'environnement classique
Créer des classes avec votre éditeur préféré (Emac, Bloc-note)
Mettre des classes dans les répertoires hiérarchiques selon leur package.
Ouvrir la console de commande
Positionner au répertoire racine (contenant les packages du plus haut
niveau)
Complier: javac [une liste des fichiers Java]
Dans l'exemple de mon_appli, ce répertoire contient le répertoire mon_appli
Ex: javac mon_appli/bd/*.java mon_appli/ihm/client/*.java
mon_appli/ihm/admin/*.java
Exécuter: java [le nom qualifié la classe main]
Ex. java mon_appli.ihm.client.ProductBrowser
NB. il faut positionner dans le bon répertoire (pour que la JVM puisse trouver les
classes nécessaires)
38
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Utilisation de lDE Eclipse
Créer un projet
Créer des classes dans le répertoire source (par défaut c'est le
répertoire du projet)
File New class
La complication se fait automatiquement lors de la sauvegarde des
classes.
File New projet
Les erreurs syntaxiques sont soulignées ☺
Exécution
Sélectionner la classe <<main>>
Cliquer droit Run as Java Application
39
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Débuggage
Le débuggage permet d'analyser le comportement du programme lors de son exécution
Découvrir des erreurs.
L'idée consiste à arrêter un programme à un moment donné et à examiner l'état des objets du
programme.
Debuggeur: un JVM qui offre le moyen d'arrêter l'exécution du programme à une ligne spécifiée
(appelé point d'arrêt).
Ex.
jdb (IHM ligne de commande)
usage: jdb [nom de la classe main]
Eclipse (IHM graphique)
usage: sélectionner la classe main,
cliquer droite Debug as Java Application
Différentes manières pour reprendre l'exécution
Passer à la ligne suivante ("step over")
Entrer dans le code de la méthode qui va être invoquée ("step into")
Exécuter juste à la fin de la méthode et retourner à l'objet invoquant la méthode
("step return")
Exécuter juste au point d'arrêt suivant ("resume")
40
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Débuggage avec Eclipse
Contrôle de la reprise
d'exécution
Etat des objets et
variable locales
La pile d'invocation
(qui appelle qui)
Point d'arrêt
41
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Documentation (javadoc)
La documentation facilite l'entretien de logiciel.
Un exemple: la documentation des classes standard Java
Réutiliser, corriger des erreurs, faire évoluer, etc.
http://java.sun.com/j2se/1.4.2/docs/api/
On peut générer automatiquement le document à partir du code source ☺
Mais il faut mettre des commentaires sur le code source !
Ex. La classe String offre la méthode subString(…) permettant d'extraire une partie de la chaîne
de caractères.
42
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Question : utilisation de la
documentation
Chercher la description de la classe Integer
Chercher la classe Characters
Quelle méthode permet de convertir une chaîne de
caractères vers un nombre entier (int) ?
Quelle méthode permet de tester si un caractère est
minuscule ou majuscule
Chercher la classe StringTokenizer
Ecrire un programme permettant de couper une phrase en
mots et les afficher (un mot par ligne).
Conseil : méthodes hasMoreToken(), nextToken()
String: "chercher une
class"
afficher
chercher
une
class
43
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Documentation:
ajouter des commentaires au code
Entre /**
Devant la déclaration d'une classe, d'une méthode, ou d'un attribut
Mot clé:
*/ (et non /* */ ).
@param, @return, @exception
44
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Documentation: la génération
Avec ligne de commande
javadoc
[fichiers Java]
Avec Eclipse
Sélectionner
le package
Cliquer droite Export Javadoc
Il est conseillé de rendre le javadoc généré
dans le compte rendu du contrôle continu.
45
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Déploiement
déploiement d'applications sous forme de fichiers d'archivage (JAR)
Un fichier jar ressemble à un fichier ZIP.
Il contient:
Des classes compilées
Du code source (optionnel)
Des données nécessaires pour l'application
(ex. images, données de configuration)
Comment créer un fichier JAR
Ligne de commande
jar cvf [liste des fichiers]
Eclipse
Sélectionner le package
Cliquer droite Export JAR file
46
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Déploiement: comment utiliser le fichier JAR
?
Pour exécuter la classe main localisé dans
un fichier jar, il faut dire à la JVM de
chercher la classe dans ce fichier
Utiliser le paramètre cp (classpath)
Ex.
java -cp messenger.jar
poo.messenger.Main
47
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 3.1 Création et exécution d'une
application
Créer l'application Messenger avec
Eclipse
48
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 3.2 Débuggage
Débugger l'application Messenger avec Eclipse
Mettre le point d'arrêt sur
pierre.ajouterContact(julien);
Examiner les 3 objets messenger
Utiliser le contrôle de la reprise d'exécution pour entrer dans la classe Vector:
Comment la classe Vector stocke t-elle les objets Messenger?
A quelle index du tableau l'objet sera-il ajouté?
Fixer un autre point d'arrêt à
System.out.println(idUtilisateur + " recoit: " + texte);
dans la méthode recevoir (…)
Reprendre l'exécution jusqu'à ce point d'arrêt ("resume")
Examiner la pile d'invocation
Qu’ indique t-elle?
Quel objet Messenger est-il en train de recevoir un texte ?
Refaire "resume" et observer la différence dans la pile d'invocation
Dans chaque étape, faire la capture-écran et répondre aux questions
49
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 3.3 Java Doc
Générer un javadoc de l'application
Messenger avec Eclipse
Ajouter des commentaires au code et
régénérer le javadoc
50
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
4. Concepts POO
(avancés)
Contenu:
Héritage (Polymorphisme, Interface, Class abstraite,
relation <<instance de>>, casting)
Visibilité et encapsulation
Attributs et Méthodes statiques
Exception
51
Héritage
Une héritage est une relation entre
deux classes.
Ex. Etudiant hérite de Personne:
Object
La classe étudiant et un sous-type
(sous-classe) de la classe Personne
(superclasse).
Personne
Syntaxe: mot clé "extends"
public class Etudiant extends
Personne {
…}
En Java, une classe ne peut pas
hériter de plus d'une classe.
Si l'héritage n'est pas déclaré, la
classe hérite implicitement de
java.lang.Object
Etudiant
une
Enseignant
hiérarchie de classes
52
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sémantique d'héritage:
attributs et méthodes
La sous classe (ex. Etudiant) possède des attributs et des méthodes
définis dans la superclasse (ex. Personne).
Ex.
public class Personne {
String nom;
public class Etudiant
extends Personne {
String noEtudiant;
Etudiant(String _nom, _noEtudiant) {
nom = _nom;
noEtudiant = _noEtudiant;
envoyerMail("[email protected]",
"creation de dossier : " + nom);
}
public void envoyerMail(
String adr, String message)
{ ….}
}
}
53
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sémantique d'héritage: redéfinition
(autrement dit spécialisation, <<overriding>>)
La sous classe peut redéfinir les méthodes déjà existant dans la
superclasse.
Les méthodes redéfinies doivent garder la même signature.
Ex.
public class Personne {
String nom;
public void afficher() {
System.out.println(
"Personne : " + nom);
}
}
public class Etudiant extends
Personne {
…
public void afficher() {
System.out.println(
"Etudiant : " + nom
+ " no: " + noEtudiant);
}
}
54
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Etude de cas: redéfinition de la méthode
equals(…)
Comparaison par identité
Deux variables de type objets sont égales si elles référencent le même objet
(opérateur ==)
Ex.
Comparaison par le contenu
String s1 = "hello"; String s2 = "hello"; String s3 = s1;
System.out.println(s1 == s2); // false : pas le même objet
System.out.println(s1 == s3); // true
Deux objets sont égaux si leur contenu se ressemble.
Personnalisation de comparaison
La classe Object propose la méthode <<boolean equals(Object unAutre)>> pour
comparer deux objets.
Elle peut être redéfinie pour personnaliser la façon de comparaison.
Les classes standard Java (ex. String, Integer) redéfibir equals(…) pour appliquer la
comparaison par contenu.
Ex. System.out.println(s1.equals(s2)); // true
55
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple: redéfinition de la méthode
equals(…)
Object
public Personne {
String noSecu;
…
public boolean equals(Object autre) {
if(autre instanceof Personne) {
Personne p2 = (Personne) autre;
if(noSecu.equals(p2.noSecu))
return true;
}
return false;
}
}
equals(…) {
// comparer par
identité
}
Personne
equals(…) {
// comparer par
contenu (no de sécu
sociale)
}
String
equals(…) {
// comparer
par contenu
}
56
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Accès aux méthodes redéfinies dans la superclass
Même si la sous classe redéfinit des méthodes de la superclasse,
elle a le moyen d'accéder à ces méthodes en utilisant le mot clé
<<super>>.
public class A {
public A(String s) {
System.out.println("A : " + s);
}
public void m1() {
System.out.println("A.m1");
}
public void m2() {
System.out.println("A.m2");
}
}
// main
B b= new B("hello");
b.m1();
public class B extends A {
public B(String s) {
super(s);
System.out.println("B : " + s);
}
public void m1() {
super.m1();
m2(); // pas besoin de faire super.m2();
System.out.println("B.m1");
}
}
Résultat :
A : hello
B : hello
A.m1
A.m2
B.m1
57
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sémantique d'héritage: Substituabilité
L'objet instance de la sous-classe peut se substituer là
où l'objet instance de la superclasse est requis.
Ex1.
Personne p = new Etudiant();
Ex.2.
Soit la méthode imprimerInfoPersonne() définit
public void imprimerInfoPersonne(Personne p)
{ … }
Il est possible de passer l'objet Etudiant comme le paramètre.
Etudiant e = … ;
inprimante.imprimerInfoPersonne(e);
58
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
getClass() et instanceof :
Retrouver le type objet.
Le problème:
methode(Object param) {
// param est-il un Etudiant? un Enseignant? ou autre?….
}
La solution:
getClass() : retrouver la classe d'objet
// obtenir le nom de la classe de l'objet
System.out.println(param.getClass().getName());
Instanceof : tester le type d'objet
// supposant que param est instance de la classe Etudiant
System.out.println(param instanceof Etudiant); // true
System.out.println(param instanceof Personne); // true
System.out.println(param instanceof Enseignant); // false
59
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Casting: convertir une variable vers un type plus
spécifique
Le problème :
Object o = …. ;
if(o instanceof Etudiant) {
// o.afficher(); illégal
// Maintenant on sait que o est de type Etudiant,
// mais comment invoquer la méthode afficher()
// de la classe Etudiant?
}
La solution: Casting.
Etudiant e = (Etudiant) o;
// les variable e et o référencent le même objet
// mais elles sont de différents types.
e.afficher();
60
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sémantique d'héritage: Polymorphisme
Le polymorphisme est le fait qu'une classe peut avoir plusieurs sousclasses.
Ex: Personne a comme sous-classes Etudiant et Enseignant.
Par principe de substituabilité, le programme qui traite les objets Personnes
n’a pas besoin de distinguer les objets Etudiant de ceux d'Enseignant
public class Afficheur {
Personne[] personnes;
….
public void afficherToutePersonne() {
for(int i=0; i<personnes.length; i++) {
personnes[i].afficher(); // affichage d'un Etudiant
// et celui d'un Enseignant peuvent être différents.
}
}
}
61
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interface: type abstrait
Une interface est un type
abstrait, censé être
implémenté par des
classes.
Il ne contient que les
méthodes sans corps.
Ces méthodes sont à
redéfinir dans les classes
d'implémentation
On ne peut pas créer une
instance d'une interface
mais on peut créer une
instance d'une classe
d'implémentation.
<<Interface>>
AdaptateurWifi
envoyerDonner(..)
recevoirDonner(..)
AdaptateurWifiImpl1
envoyerDonner(..) {
.. }
recevoirDonner(..)
{ .. }
AdaptateurWifiImpl2
envoyerDonner(…)
{.. }
recevoirDonner(...)
{ .. }
62
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interface: héritage multiple
Une classe peut hériter
de plusieurs interfaces.
Chaque interface
représente un rôle d'une
classe.
Ex. un Lecteur CD-DVD
a comme rôles
LecteurCD et
LecteurDVD
<<Interface>>
LecteurCD
lirePiste(…)
…
<<Interface>>
LecteurDVD
selectionnerLanguage();
…
LecteurCdDvdImpl
lirePiste(…);
selectionnerLanguage(...);
….
63
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interface: syntaxe
interface nom_de_l'interface [ extends noms
d'autres interfaces ] {
public void methode1(String param1) ;
public int methode2(int param1, int param2) ;
// autres méthodes …
}
Le mot clé "extends" permet à une interface
d'hériter d'autres interfaces (une ou plusieurs)
64
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Implémentation d'une interface
Une classe implémentant une interface doit redéfinir
toutes les méthodes déclarées dans l'interface.
public class LecteurCdDvdImpl
implements LecteurCD, LecteurDVD {
public void lirePiste(int noPiste) {
…. // à faire
}
public void selectionnerLangue(String lang) {
…. // à faire
}
}
65
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les classes abstraites
Une classe abstraite est incomplète
Elle
ne peut être utilisé telle quelle.
Elle est censée être spécifiée par des sous classes.
On ne peut pas créer une instance d'une classe
abstraite.
Une classe abstraite peut avoir des méthodes
vides
(à redéfinir par des sous-classes).
66
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'une classe abstraite
public abstract Feneitre {
// attributs génériques pour tout type de fenêtres.
int posX; int posX;
int dimX; int dimY;
// Les méthodes dont l'implémentation est générique
// (pour tout type de fenêtres).
public void deplacer() { … }
public void redimensionner(int newDimX, int newDimY) {
dimX = newDimX; dimY = newDimY;
rafraichirContenu();
}
// la méthode dont on ne connaît pas encore l'implémentation
// (cela dépend de type de fenêtre). Ainsi on la laisse vide.
public abstract rafraichirContenu();
}
67
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Visibilité: modificateur public/private
Le modificateur public marque que les attributs/ méthodes d'une
classe sont accessibles partout (dans les classes).
Le modificateur private marque que les attributs/ méthodes d'une
classe ne sont accessibles que dans cette classe.
class C1 {
public String a1;
private String a2;
public void m1();
private void m2();
}
class C2 {
void m3() {
C1 c1 = new C1();
c1.a1 = "hello"; // OK
// c1.a2 = "hello"; illégal
c1.m1(); // OK
// c1.m2(); illégal
}
}
68
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Visibilité :
autre modificateurs de visibilité
Les autres modificateurs sont:
aucun modificateur (par défaut): les attributs/ méthodes sont accessibles
par les classes du même package
protected: les attributs/ méthodes sont accessibles
par les classes du même package, et
par les sous-classes de la classe courante.
package p1;
public class A {
int a1;
protected int a2;
}
public class B {
// a1, a2 accessible
}
package p2;
public class C {
// a1, a2 non accessible
}
public class D extends A {
// a1 non accessible
// a2 accessible
}
69
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Encapsulation : principe
// pas d'encapsulation
public class Date {
public int jour;
public int mois;
public int annee;
}
// modification illégale
Date d1 = new Date();
d1.jour = 30;
d1.mois = 2;
d1.annee = 2006;
Principle d'encapsulation :
Une
classe devrait cacher des attributs et exposer
ses méthodes au monde extérieur (aux autre classes)
Protéger le contenu (les attributs) de la modification illégale
Masquer les détails internes de la classe
simplification
70
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Encapsulation: Protection du contenu
public class Date {
private int jour;
private int mois;
private int annee;
public Date() {
… // initialisé à la date aujourd'hui
}
public boolean setDate(int j, int m, int a) {
if( estDateValide(j, m, a) ) {
jour =j; moi=m; annee=a; return true;
} else { return false; }
}
…
}
Seule la
modification
valide est
permise
71
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Encapsulation:
Masque de détails internes
public class Image {
// séquence d'octets au format propriétaire
private byte[] donnees;
public void chargerDeFichier(File ficher) {
… // charger et convertir au format propriétaire
}
public void afficher() {
…. // interpréter le format propriétaire.
}
}
L'utilisateur n‘a pas besoin de connaître le
format de données pour utiliser cette
classe
72
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Membres statiques
Le modificateur « static » peut s'appliquer à une
méthode ou à un attribut d’une classe.
L'élément statique est partagé par toutes les instances
de la classe.
Il est possible d’y accéder sans disposer d’une instance,
mais directement par la classe.
Ex : une méthode statique
public class Calculatrice {
public static int valeurAbsolue(
int i ) {
if(i < 0) return -1 * i;
return i;
}
}
// OK
System.out.println(
Calculatrice.valeurAbsolue(-25) );
// pas besoin de faire cela:
Calculatrice c = new Calculatrice();
System.out.println(
c.valeurAbsolue(-25) );
73
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Membres statiques: Exemple
public class Test {
static int comptoir = 0; // initialiser
lors du chargement de la classe
int id;
public Test() {
id = comptoir; // utiliser le comptoir
comme identifiant d'objet
comptoir ++; //incrémenter le
comptoir à chaque instanciation
}
public imprimerId() {
System.out.println(id);
}
public static imprimerComptoir() {
System.out.println(comptoir);
}
}
public static void main(String[] args) {
Test t1 = Test();
Test t2 = Test();
Test t3 = Test();
Test.imprimerComptoir(); // résultat?
t1.imprimerId(); // résultat ?
t2.imprimerId(); // résultat ?
t3.imprimerId(); // résultat ?
}
Les méthodes statiques ne
peuvent accéder qu’aux
attributs statiques.
74
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Définition de constants
Un constant peut être défini comme un attribut d’une
classe,
avec déclaration <<static>> (partagée par toutes les
instances) et <<final>> (sa valeur est non modifiable)
Par convention le nom d'un constant est tout en
majuscules.
public class MesConstants {
public static final int LOAD = 0;
public static final int SAVE = 0;
public static final int MOVE = 2;
}
75
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exception
Une exception représente un problème produit lors de l'exécution.
Ex.
NumberFormatException
Integer.parseInt("vingt trois"); // un problème
Une application robuste doit pouvoir gérer des exceptions.
Scénario d'utilisation
1) Une exception créée et jetée (par un module d'appli. Ex, classe C1)
2) Une exception est saisie et traitée (par un autre module appli. Ex,
classe C2)
76
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'une exception
public class FileLoader {
public static byte[] load(String fileName) throws FileNotFoundException {
if(…) { // si le fichier inexistant
throw new FileNotFoundException(fileName);
} … // chargement normal
}
}
public class MonAppli {
public static void main(String[] args) {
String fileName = …;
try { // tentative d'une opération susceptible de générer une exception
byte[] contenu = FileLoader.load(fileName);
print(contenu);
} catch(FileNotFoundException e) { // traitement d'une exception
System.out.println(e); }
}
}
77
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Définition des types d'exceptions
On peut définir différents types d'exception.
Ex: appli sécurisée:
AuthentificationFailedException, InvalidUserNameException, InvalidePasswordException.
Un type d'exception : une classe héritant de java.lang.Exception.
On peut définir des attributs pour représenter l'info spécifique à un type d'exception
public class AutentificationFailedException
extends Exception {
// information sur la date de la tentative de
l'authentification et le nom de utilisateur
java.util.Date date = new Date();
String userName;
public AutentificationFailed(String userName) {
this.userName = userName
}
}
public class InvalidUserNameException extends
AuthentificationFailedException {
public InvalidUserNameException(String userName)
{
super(userName)
}
}
78
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
La déclaration <<throws>>
La déclaration <<throws>> marque qu’une méthode est susceptible
d’émettre une exception.
La méthode peut produire une exception elle-même (avec opérateur
<<throw>>) ou faire passer une exception produite par une autre méthode
public class LoginManager {
public void login(String userName, String password) throws
AuthentificationFailedException, ConnectException {
…. throw new InvalidUserNameException(userName);
}
}
public class TransactionManager {
public void doTransaction() throws AuthentificationFailedException,
ConnectException {
… loginManager.longin(userName, password);
….
}
}
génératrice de
l'exception
Appelle
faire passer
l'exception
79
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Trace d'une exception
La trace d'une exception informe
sur l'origine de l'exception
Facilité de débuggage
Elle est une chaîne d'appels de
méthodes
MonAppli.main()
TransactionManager.doTransaction()
LoginManager.login
throw new InvalidUserNameException(…)
de la méthode génératrice de
l'exception jusqu'à la méthode
main
Elle est stockée dans l'exception.
Affichage de la trace :
Chaîne d'appels :
catch(Exception e) {
e.printStackTrace();
}
Affichage :
InvalideUserNameException : jlopez
at LoginManager.login (line 124)
at TransactionManager.doTransaction (line 250)
at MonAppli.main (linge 78)
80
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Le traitement d'exception
try {
…
} catch(ExceptionType1 e) {
…
} catch(ExceptionType2 e) {
…
}
81
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.1 : Héritage et redéfinition
de méthode
Implémenter une application avec des classes Personne,
Etudiant, Enseignant et Afficheur.
Un affichage d'un Etudiant et celui d'un Enseignant prennent les
formes:
Les classes Etudiant et Enseignant redéfinissent la méthode
<<afficher()>> de la classe Personne.
Etudiant : [nom] no : [noEtudiant] promo : [promo]
Enseignant : [grade] [nom]
Question
Si on n’utilisait pas le concept de la redéfinition:
Comment pourrait-on réaliser cette application (avec <<instanceof>>) ?
Si on ajoute dans le futur d'autres sous-classes de Personne, y aurait-il
un modificafication ?
82
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.2 (1/5) :
Manipulation des liens entre des objets
Notre application gère le système de ficher.
Elle se base sur:
Un fichier a un nom et son contenu.
On constate que le fichier et le répertoire
ont des caractères communs
Un répertoire a un nom.
Un répertoire peut contenir des éléments qui
sont soit des fichiers, soit des répertoires
Classe Fichier
Attribut
représentant le
contenu d'un
répertoire
Classe Répertoire
Element
Les deux portent un nom.
Les 2 peut être contenus par un répertoire.
Ainsi on crée la classe Element représentant
ces caractères communs
A faire: Définir en Java les classes Ficher,
Répertoire et Element
Fichier
Attribut
représentant le
répertoire
conteneur
Repertoire
83
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.2 (2/5)
Définir les méthodes permettant de:
Modifier le nom d'un fichier / répertoire
Modifier le contenu d'un fichier
Déplacer un fichier / répertoire
Dans la classe Répertoire, écrire une méthode permettant
d'afficher le contenu du répertoire récursivement.
Ecrire une classe main pour tester cette appli.
Créer une arborescence de fichier
Afficher cette arborescence
La modifier.
Afficher le résultat
84
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.2 (3/5) : Scénario de test
move Projet Doc
erreur attendue (boucle)
rename Projet/Doc/Doc1.doc DocInterne
erreur attendue (conflit de noms)
move Projet/Doc Projet/src
move Projet/src/Doc/Doc2.doc Projet/src
rename Projet/src/Doc/Doc1.doc Doc2.doc
move Projet/src/Doc/Doc2.doc src
erreur attendue (conflit de noms)
moveReplace Projet/src/Doc/Doc2.doc src
écrasement attendu
Affichage du répertoire (état initial) :
[R] Projet
[R] Projet/Doc
[F] Projet/Doc/Doc1.doc : "contenu du Doc1.doc"
[F] Projet/Doc/Doc2.doc : "contenu du Doc2.doc"
[F] Projet/Doc/Doc3.doc : "contenu du Doc3.doc"
[R] Projet/Doc/DocInterne
[R] Projet/src
[F] Projet/src/Class1.java: "class Class1 {}"
…
[R] Projet/bin
[F] Projet/bin/Class1.class: "010000111"
[R] = Répertoire
[F] = fichier
85
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.2 (4/4) IHM
Créer la class IHM permettant à l'utilisateur
d'interagir avec le système via les méthodes
suivantes
void
move(String cheminSource, String
cheminDestination, boolean canReplace);
void rename(String chemin, String nouveauNom);
86
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.2 (5/5) : Manipulation d'exception
Ajouter la manipulation des exceptions dans le système de fichiers (TP
précédent).
Définir les types d'exceptions suivantes :
InvalidName : l'utilisateur tente de nommer un fichier/ répertoire avec des
caractères non valides ( / \ : < > ? * |) ou la longueur du nom excède 20
caractères.
NameConflict : l'utilisateur tente de nommer un fichier avec un nom déjà pris
par un des éléments dans le même répertoire
OwnershipViolation : l'utilisateur tente de déplacer un répertoire dans un
répertoire successeur.
L'information que doivent porter les exceptions :
InvalideName, NameConflict : le nom causant le problème
OwnershipViolation : la tentative de déplacement (le répertoire à déplacer et le
répertoire destinataire)
Faire un scénario de test pour chaque cas d'exception
87
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.3 (1/4) : Réalisation des interfaces du
mécanisme d'événements
Le mécanisme d'échange d'événements est très utilisé dans les
applications d'aujourd'hui.
Ce mécanisme se base sur 3 rôles:
L’interface Sujet définit le rôle des objets qui peuvent émettre des
événements.
L’interface Observateur définit le rôle des objets désirant recevoir
des événements
L’interface Evenement définit les objets contenant chacun une
information quelconque (selon le type d'événement)
Le sujet offre une méthode pour inscrire des observateurs.
L'observateur offre une méthode pour être notifiée lorsqu’un
événement est émis.
A faire: définir les interfaces Sujet, Observateur, Evenement
88
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.3 (2/4) : Implémentation générique
On souhaite implémenter cette application de
manière générique avec la classe abstraite
SujetAbstrait.
Elle
implémente le mécanisme pour maintenir la
liste des Observateurs inscrits à ce sujet
Elle offre la méthode (non abstraite) :
void diffuserEvenement(Evenement ev);
Cette méthode sera utilisée par les classes spécialistes
pour diffuser des événements quelconques.
89
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.3 (3/4) : Application sur le ebusiness
Notre application est composée de
Les classes FournisseurA, FournisseurB, FournisseurC représentent
différents fournisseurs de produits dans le marché. Elles prennent le rôle de
Sujet. Elles émettent des événements sur des offres de produits. Chaque
fournisseur offre un différent produit.
Les classes MagasinA et MagasinB ont le rôle d'Observateur. Elles
souhaitent recevoir des offres de produits. Lorsqu’elles reçoivent des offres,
elles affichent
[MagasinB/ MagasinB] recu l'offre [nomProduit, prix, tempsLivraison] [accepte/
rejete]
MagasinA accepte les produits moins chers que 100 euros.
MagasinB accepte les produits livrables dans 7 jours maxi.
La classe OffreProduit a le rôle d'événement. Elle contient l'information sur
le nom du produit, le prix, le temps de livraison.
A faire: Implémenter ces classes.
Utiliser la classe SujetAbstrat
90
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 4.3 (3/4) : Test
Définir un scénario de diffusion d'offres
Dans les classes FournisseurA, B, C définir la méthode :
public void diffuserToutesOffres() {
// ici on diffuse toutes les offres en répétant l'appel à la méthode
// diffuserEvenement(…) hérité de la classe SujetAbstrait
}
Faire la classe main qui configure l'inscription des magasins auprès
des fournisseurs et exécuter le scénario
91
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
5. Tableaux, collections
et Map
92
Tableaux
Un tableau est une séquence d'éléments
Séquence de données primitives
Séquence de références vers objets
Ex. int[], char[], byte[]
Ex. Object[], Personne[]
On crée un tableau l'avec l'opérateur <<new>>
Ex.
int[] tab1 = new int[10];
int dim = 20; Object[] tab2 = new Object[dim];
Pour un tableau d’objets, initialement ses éléments sont <<null>>
Un tableau est lui-même un objet
On accède aux éléments du tableau avec un index (entre 0
jusqu'à la dimension -1)
On peut connaître la dimension du tableau par son attribut
<<lenght>>
93
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Un tableau est un objet
On peut affecter un tableau au variable de type
java.lang.Object
Object o = new Personne[20];
On peut découvrir le type du tableau
System.out.println(o instanceof Personne[]); // résultat : true
System.out.println(o.getClass().isArray()); // résultat : true
System.out.prinln(o.
getClass().getComponentType().getName());
// résultat : Personne
94
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Tableaux : redimension
La dimension du tableau est fixée lors de la création de l'objet (new)
Pour redimensionner, il faut :
1) Créer un nouveau tableau d'une nouvelle dimension
2) Copier les éléments de l'ancien tableau vers le nouveau
Astuce: System.arraycopy( source, position, destination, position, nombreElements );
Ex.
public static Object[] redimentionner(Object[] tab, int nouvelleDim) {
Object nouveauTab = new Object[nouvelleDim];
int dimMin = (nouvelleDim> tab.length)? tab.length : nouvelleDim;
System.arrayCopy(tab, 0, nouveauTab, 0, dimMin);
}
95
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Un tableau de tableaux
Quel est le tableau résultat de ce programme?
int[ ][ ] tab2dim = new int[5][ ]; // création de
tableau dimension 5 pour stocker des tableaux
de <<int>>
for(int i=0; i<tab2dim.length; i++) {
tab2dim[i] = new int[i+1]; // creation d'un
tableau de int
for(int j=0; j< tab2dim[i].length; j++) {
tab2dim[i][j] = j;
}
}
1
1
2
1
2
3
1
2
3
4
1
2
3
4
5
96
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Collections
Une collection manipule un ensemble d'objets
Elle possède des méthodes pour :
Ajouter/supprimer
un objet dans la collection
Obtenir les objets dans la collection
Plusieurs variations
Une
collection ordonnée une liste
Une collection filtrant la duplication des membres un ensemble
Un ensemble ne peut pas contenir le même objet plus d’une
fois.
97
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les collections prêtes à utiliser en Java
Le package java.util offre des implémentations des collections prêtes à utiliser
L’interface Collection définit les méthodes, par ex :
boolean add(Object o) : ajouter un objet dans la collection
int size() : consulter la taille de la collection
iterator() : itérer dans tous les membres de la collection. Pendant l'itération, la collection
ne doit pas être modifiée (pas ajout/suppression de membres)
boolean contains(Object o) : tester si l'objet existe dans la collection. La comparaison
d'objets se fait par la méthode equals(…).
L’interface List : des collections ordonnées (listes). Elle définit des méthodes
spécifiques aux listes, par ex :
void add(int index, Object element) : ajouter un objet dans l'index specifié.
public Object remove(int index) : retirer l'objet à l'index spécifié
Les classes Vector, ArrayList sont des implémentations de List.
La classe HashSet est une implémentation de Collection. Elle filtre la duplication
de membres.
Il n'existe pas deux objets o1 et o2 tels que <<o1.equals(o2)>> dans l'ensemble.
98
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Collection de données primitives
On a vu que les membres de collections sont des objets et non des
données primitives (int, char, double)
Afin de mettre des données primitives dans une collection, on utilise la
forme d'objets
int class java.lang.Integer
char class java.lang.Character
double class java.lang.Double
Ex.
Collection c = new Vector();
c.add(new Integer(3));
c.add(new Integer(2));
System.out.println( c.contains(new Integer(3)); // true
99
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Copier une collection
En général, les constructeurs des classes d'implémentation de
collections (Vector, ArrayList, HashSet) prennent comme paramètre
une collection source pour créer une copie.
Ex.
List v = new Vector();
v.add("a"); v.add("ab");
List copie = new Vector(v);
copie.add("abc");
System.out.println(v);
// résultat : [ a, ab ]
System.out.pintln(copie); // résultat : [ a, ab, abc ]
Il est possible d'utiliser un tel constructeur pour convertir entre
plusieurs variations de collections
un ensemble vers une liste : dans un ordre quelconque
une liste vers un ensemble : la duplication est ignorée
100
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Conversion entre tableaux et collections
Tableau vers collection
utiliser la classe java.util.Arrays
méthode : public static List asList(Object[] tab)
Attention <<Returns a fixed-size list backed by the specified array.
(Changes to the returned list "write through" to the array.)>>
Afin d'obtenir une collection indépendante du tableau, créer une copie
de la liste retournée par Arrays.asList(…)
Ex.: Object[] tab = …; List l = new Vector(Arrays.asList(tab));
Collection vers tableau
Collection c = …;
Object[] tab = c.toArray();
String[] tab2 = (String[]) c.toArray(new String[c.length])); // obtenir un
tableau d'un type spécifique
101
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Trier une liste
La classe java.util.Collections propose les méthodes pour trier une
collection.
interface Comparable :
static void sort(List list) : tirer une liste d'objet implémentant l'interface
<<Comparable>>
static void sort(List list, Comparator c) : trier une liste d'objet en utilisant
un comparateur personnalisé
propose la méthode : int compareTo(Object o); // retourne un nombre
négatif, 0, nombre positif si inférieur de, égal à, supérieur
Les objets basiques (Integer, String, Byte, Char, …) implémentent
Comparable
interface Comparator :
propose la méthode : int compare(Object o1, Object o2)
102
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Paramétrage de la collection
(Java 1.5)
Java 1.5 permet au programmer de spécifier le type d'objets qui sont membres de la
collection.
Avantages
Code plus lisible. Plus besoin de faire casting
Ex. for(Iterator it =
Détection d'erreurs lors de la complication (Ex. ajout d'objets de mauvais type dans la
collection)
// Java 1.5
List<String> v = new Vector<String>();
v.add("a"); v.add("b");
v.add(new Integer(3); // erreurs de
compliation
for(int i=0; i<v.size(); i++) {
String s = v.get(i);
v.set(i, "prefix_" + s );
}
// Java 1.4
List v = new Vector();
v.add("a"); v.add("b");
v.add(new Integer(3); // pas d'erreurs de
compliation
for(int i=0; i<v.size(); i++) {
String s = (String) v.get(i); // produire erreur
d'exécution (ClassCastException Integer to
String)
v.set(i, "prefix_" + s );
}
103
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Map
Un map (objet implémentant l'interface java.util.Map) représente un
ensemble de couples <clé, valeur>. Les clés et valeurs peuvent être
des objets de type quelconque. Il propose les méthodes :
void put(Object key, Object value) : ajouter un couple <clé, valeur> dans
le Map. S’il existe déjà un couple avec cette clé, le nouveau remplace
l'ancien.
Object get(Object key) : trouver la valeur associée à une clé.
Object remove(Object key) : retirer le couple <clé, valeur> s'il existe.
retourner la valeur retirée.
Set keySet() : obtenir toutes les clés existant dans le map.
Classes java.util.Hashtable, java.util.HashMap : implémentations
de l'interface Map
Classe java.util.Properties : une implémentation de Map dont les
clés et les valeurs sont des String.
104
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Table de hachage (Hashtable)
La table de hachage est une technique d'implémentation de Map
Un tableau de grande taille est utilisé pour stocker les couples <clé,
valeur>
Le hachage de la clé permet de trouver l'index du tableau pour
stocker le couple/ rechercher le couple.
…
stocker les couples dont leurs clés entre 0 – 99
… clés entre 100 - 199
Hachage :
… clés entre 200 - 199
l'index de 5 0
l'index de 105 1
l'index de 145 1
l'index de 213 2
105
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les objets clés doivent redéfinir la
méthodes equals(..) et hashCode()
boolean equals(Object uneAutreCle)
int hashCode()
Permet de tester si cette clé est égale à une autre clé.
Permet de trouver l'index du tableau associé à cette clé.
Contrat à respecter : si deux clés sont égales, elles doivent
retourner le même index de hachage.
Les classes standards (String, Integer, Double …)
proposent déjà l'implémentation de ces méthodes. ☺
106
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'utilisation incorrecte de
Hashtable
Problème de programmation
int[] key1 = { 1, 2, 3 };
int[] key2 = { 1, 2, 3 };
Map m = new Hashtable();
m.put(key1, "valeur de 123");
System.out.println( m.get(key1) ); //afficher <<valeur de 123>>
System.out.println( m.get(key2) ); //afficher <<null>>
m.put(key2, "nouvelle valeur de 123");
System.out.println( m.get(key1) ); //afficher <<valeur de 123>>
System.out.println( m.get(key2) ); //afficher <<nouvelle valeur de 123>>
System.out.println( key1.hashCode() == key2.hashCode()); // afficher <<false>>
System.out.println( key1.equals(key2.hashCode()); // afficher <<false>>
Les objets tableau ne proposent pas de bonne implémentation de
equals(…) et hashCode()
Ainsi key1 et key2 sont considérées comme inégales
les couples <key1, …> et <key2, …> sont stockés dans deux index différents
107
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Redéfinition de la méthode equals(…)
et hashCode()
public class IntArray { // une classe enveloppant un tableau pour redéfinir les
méthodes equals(..) et hashCode()
private int[] tab;
public IntArray(int[] tab) { this.tab = tab; }
public boolean equals(Object o) {
if(this==o) return true;
if(! (o instanceof IntArray) ) return false;
IntArray ia = (IntArray) o;
if(tab[].length != ia.tab[].length) return false;
for(int i=0; i<tab.length; i++) { if(tab[i] != ia.tab[i]) return false; }
return true;
}
public int hashCode() {
// Deux objets IntArray égaux retournent le même index.
int somme = 0;
for(int i=0; i<tab.length; i++) { somme=+tab[i]; }
return somme;
}
}
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
108
Correction du problème
int[] key1 = { 1, 2, 3 };
IntArray key1 = new IntArray(tab1);
int[] key2 = { 1, 2, 3 };
InArray key2 = new IntArray(tab2);
Map m = new Hashtable();
m.put(key1, "valeur de 123");
System.out.println( m.get(key1) ); //afficher <<valeur de 123>>
System.out.println( m.get(key2) ); //afficher <<valeur de 123>>
m.put(key2, "nouvelle valeur de 123");
System.out.println( m.get(key1) ); //afficher <<nouvelle valeur de
123>>
System.out.println( m.get(key2) ); //afficher <<nouvelle valeur de
123>>
System.out.println( key1.hashCode() == key2.hashCode()); // afficher
<<true>>
System.out.println( key1.equals(key2.hashCode()); // afficher
<<true>>
109
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 5.1 : Manipulation de tableaux
Implémenter un programme cherchant un Objet dans un
tableau
méthode : int chercher(Object s, Object[] tab)
retourner l'index si trouvé (sinon retourner -1)
Tester ce programme avec cette méthode main :
public static void main(String args) {
Object[] tab = { "a", null, "ab", null, '"abc", "abcd" };
// initialisation d'un tableau
System.out.println( chercher("ab", tab) );
System.out.println( chercher("xyz", tab) );
}
110
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 5.2 (1/1) : Manipulation de listes
Ecrire un programme permettant d'inverser l'ordre
des membres d'une liste, sans modifier la liste
originale
Ecrire un programme permettant d'inverser une liste
en modifiant la liste originale
public List inverser(List org)
public void inverserModif(List org)
Ecrire un programme permettant de filtrer des
membres de collections (de type Integer) qui sont
inférieur à 0.
public Collection filtrer(Collection intCollection)
111
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 5.2 (1/2) : Manipulation de listes
On propose l'interface Filtre permettant de définir un filtre personnalisé :
Ecrire un programme permettant de filtrer une collection avec un filtre
personnalisé
public void Collection filtre(Collection c, Filtre f)
Ecrire une classe d'implémentation de filtre (classe FiltreIntPair) pour filtrer
des objets de type Integer
public interface Filtre {
public boolean estFiltre(Object o); // vrai si l'objet est à filtrer
}
Les nombres impairs sont filtrés
Ecrire un programme prenant en arguments de ligne de commande une liste
à filtrer
Ex. java poo.tp5_3.MainClass 2 4 6 13 15 17 20
Astuce: en Eclipse, on spécifie les arguments de ligne de commande avec le menu
Run Run l'onglet Arguments
112
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 5.3 : Map multivalué
Créer un map permettant d’associer une clé à plusieurs valeurs.
Le principe consiste à utiliser le map <<normal>> associant une clé à une liste de
valeurs.
Implémenter la classe MultivalueMap
public class MultivalueMap {
Map<Object, List> map = new Hashtable<Object, List>(); // un map normal
public void put(Object key, Object value) { … }
public List get(Object key) { …}
public List remove(Object key) { … } // supprimer toutes les valeurs associées à la clé et
retourner les valeurs supprimées.
public boolean remove(Object key, Object value) { … } // supprimer une seul valeur
retourner vrai si la valeur a existé (et donc a été supprimée)
}
Est-ce que la modification de la liste retournée par la méthode get(…) affecte les
données stockées dans le map? Proposer l'implémentation de get(..) qui empêche
cela.
Appliquer ce map pour stocker l'info sur les étudiants et leurs cours. Ex :
put ("000123", "Systèmes I" ) : étudiant no 000123 prend le cours "Systèmes I"
put ("000123", "OOP") : cet étudiant prend également le cours OOP
put ("000124", "Anglais I" )
Ajouter la méthode affichant tous les couples du map sous forme d'une table.
L'affichage doit respecter l'ordre descendant des numéros d'étudiants.
113
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 5.4 (1/2) : Map de données les plus
récemment utilisées
Créer la classe <<CacheMap>> proposant les
comportements suivants:
Elle a une capacité de stockage limitée (à configurer lors de
l'instanciation de la classe). Elle ne peut stocker que N couples.
Lors qu'elle atteint sa capacité et que le programmeur tente
d’ajouter un nouveau couple, elle supprime le couple le moins
récemment utilisée (LRU: Least Recently Used).
Pour identifier le couple LRU, elle maintient le classement de
ces clés selon l’ordre d’accès (via put/get)
CacheMap hérite de la classe Hashtable et redéfinit
certaines de ses méthodes.
114
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 5.4 (2/2) : Scénario de teste
public static void main(String[] args) {
CacheMap m = new CacheMap(1000) ; // capacité 1000
for(int i=0; i<10000; i++) {
m.put(new Integer(i), new Integer(i * 2));
m.get(34);
}
System.out.println("la Map est de taille : " + m.size() ) ;
// attendu : 1000
System.out.println("la valeur de 9956 est : " + m.get(new Integer(9956));
// attendu : 2 fois 9956
System.out.println("la valeur de 35 est : " + m.get(new Integer(35));
// attendu : null
System.out.println("la valeur de 34 est : " + m.get(new Integer(34));
// attendu : 2 fois 34.
}
115
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
6. Manipulation des
Entrées/ sorties
flux et fichiers
116
Les entrées-sorties
Le package « java.io » permet de gérer la manipulation
d’entrées / sorties.
Les entrées et les sorties sont des flux de données
flux entrants : le programme peut lire les données.
flux sortants : le programme peut y émettre des données.
Source de données
Un flux connecte un programme avec une sources de données
Ex. écran/clavier, fichiers, connexion TCP/TP, Web
Web
Programme
fichier
117
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Flux abstraits
Abstraction
Classe abstraites
Permet au programme de lire/écrire des données de différentes sources
de données de la même manière.
Ex. On peut utiliser le même code pour lire des fichiers et des pages
web.
java.io.InputStream/ java.io.OutputStream : flux entrant/ sortant pour
données brutes (octets)
java.io.Reader/ java.io.Writer : flux entrant/ sortant pour données textes
uni codes (16 bits)
Exception
java.io.IOException : représente des problèmes de la connexion de flux
Dépendant des sources dé données : Fichiers, Web
118
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Flux d'octets
InputStream propose les méthodes:
int read() : lire un octet (retourné en int), -1 si le flux est terminé.
int read(byte buf[]) : lire une séquence d'octets et la mettre dans
buf, retourner un nombre d'octets lus (entre 0 et buf.length), -1 si
le flux est terminé.
close() : fermer le flux, libérer des ressources associées.
OutputStream propose les méthodes:
void write(int b) : écrire un octet (représenté avec int) dans le flux
void write(byte buf[]) : écrire une séquence d'octets dans le flux.
flush() : Si la mémoire tampon est utilisée, envoyer toutes les
données de la mémoire tampon vers la destination.
close() : terminer l'écriture sur la source de données.
119
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Flux de caractères
Reader propose les méthodes:
int read() : lire un caractère (retourné en int), -1 si le flux est terminé.
int read(char buf[]) : lire une séquence de caractères et la mettre dans
buf, Retourner un nombre de caractères lus (entre 0 et buf.length), -1 si
le flux est terminé.
close() : comme InputStream
Writer propose les méthodes:
void write(int c) : écrire un caractère (représenté avec int) dans le flux
void write(char buf[]) : écrire une séquence de caractères dans le flux.
flush() : comme OutputStream
close() : comme OutputStream
120
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Flux concrets
les classes abstraites InputStream/ OutputStream et Reader/ Writer
sont à spécialiser pour représenter des flux concrets
Exemple de flux d'octets
FileInput(Output)Stream : lire/ écrire des fichiers
ByteArrayInput(Output)Stream : lire/ écrire des octets dans un tableau
via les méthodes de InputStream/ OutputStream
ObjectInput(Output)Stream : lire et écrire des objets dans un flux
quelconque (fichiers, réseaux)
Exemples de flux de caractères
FileReader(Writer) : lire/ écrire des fichiers textes
StringReader(Writer) : lire/ écrire des caractères dans un String via les
méthodes de Read/ Writer.
121
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple : lecture/écriture de fichers
import java.io.*;
public class Copy {
public static void main(String[] args) throws IOException {
FileReader in = new FileReader("c:/source.txt");
FileWriter out = new FileWriter("c:/destination.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
in.close(); // déverrouiller (lecture seule) le fichier
out.close(); // écrire les données de la mémoire tampon
vers le fichier et le fermer
}
}
122
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Lecture bloquante / non bloquante
La lecture de données du flux peut engendrer un délai
Ex. Congestion de réseaux.
Le programme peut effectuer la lecture de deux
manières
Bloquante : le programme attend jusqu'à ce que les données
soient disponibles
InputStream.read(), Reader.read() : le programme ne sort de ces
méthodes que quand un octet / caractère est prêt à retourner
Non bloquante : le programme obtient uniquement les données
actuellement disponibles
InputStream.read(byte[] buf), Reader.read(char[] buf) : Si les
données ne sont pas encore disponibles, alors la méthode retourne
0 comme le nombres d'octets/ caractères lus.
123
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Emballage (wrapping) de flux
Certains types de flux peuvent emballer un autre flux.
Ex.
BufferedInput(Output)Stream, BufferedReader(Writer) propose la gestion de mémoire
tampon. Augmenter la performance
Le programme lire/ écrire des données sur la mémoire tampon. Ces données sont
transférées de /vers le flux emballé.
Les classes de flux qui peuvent emballer proposent un constructeur prenant comme
paramètre le flux à emballer
Ex.
InputStream input = …; // flux entrant à emballer
BufferedInputStream in = new BufferedInputStream(input);
OutputStream output = …; // flux sortant à emballer
BufferedOutputStream in = new BufferedOutputStream(output);
124
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Flux de connexion de réseaux
Lecture d'une URL
java.net.URL
url = new URL("http://www.yahoo.com");
InputStream in = url.openStream();
Flux TCP/TP
java.net.Socket
socket = new Socket("
www.yahoo.com", 80);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
125
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Manipulation de flux de caractères entrants
La classe java.io.BufferdReader propose une méthode
pratique pour lire chaque ligne de texte d'un flux emballé
(InputStream).
Ex.
InputStream in = new FileInputStream("c:/note.txt")
BufferedReader br = new BufferReader(in);
String ligne = br.readLine();
Pour analyser la ligne lue, utiliser la classe
java.util.StringTokenizer
Ex.
StringTokenizer st = new StringTokenizer(ligne);
while(st.hasMoreToken()) {
String t = st.nextToken();
System.out.println(t);
}
126
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Manipulation de flux de caractères sortants
La classe java.io.PrintWriter propose des méthodes pratiques pour écrire différents
types d'information sous forme textuelle vers un flux emballé (OutputStream).
Ex. print(int i), print(boolean b), print(String s), print(Object o) ….
println(int i), println(boolean b), println(String s), println(Object o)….
Pour transformer un objet vers du texte [print(Object o)], la méthode toString() de
l'objet est invoquée. La classe de l'objet peut fournir l'implémentation de toString()
pour proposer la représentation textuelle de l'objet.
Ex.
Personne {
String nom; …
public String toString() {
return "Personne : " + nom;
}
}
OutputStream out = … ;
PrintWriter w = new PrintWriter(out);
Personne[] tab = …;
w.println("Les membres de l'équipe")
for(int i=0; i<tab.length; i++) {
w.println(tab[i]);
}
127
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les flux d’entrée et de sortie standard
Le flux d’entrée standard : System.in (instance
de InputStream)
Par
défaut, la source de donnée est le clavier
Flux standard de sortie (instance de PrintWriter):
System.out
: le flux sortant qui, par défaut, s’affiche à
l’écran
System.err : le flux sortant pour les erreurs (qui, par
défaut, s’affiche également à l’écran )
128
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Connexion de deux modules de programme avec
un tuyau (<<pipe>>)
Un programme peut être divisé en plusieurs modules. Chaque module effectue une
tache parallèle.
Un tuyau permet la communication entre les modules.
un module permet d'envoyer des données à un autre module par un flux.
Le module producteur : envoie des données par PipeWriter ou PipeInputStream
Le module consommateur : renvoie les données par PipeReader ou PipeInputStream
Etablissement de connexion de modules
PipedWriter pipeOut = new PipedWriter();
PipedReader pipeIn = new PipedReader(pipeOut);
// pipeOut est utlisé par le producteur
// pipeIn est utlisé par le concomateur
Module producteur
utilise PipeWriter ou
PipeOutputStream
Module consommateur
utilise PipeReader ou
PipeInputStream
129
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sérialisation et reconstitution d'objets à
travers un flux
La classes ObjectInput(Output)Stream permettent de lire et écrire des
objets du programme
Cas d'utilisation
Sauvegarder l'état du programme dans un ficher pour pourvoir recharger plus
tard
Envoyer des objets d'un programme à un autre programme.
Elle propose les méthodes
void writeObject(Object o) : écrire un objet vers le flux. L'écriture d'objet consiste
à écrire l'état de l'objet (tous les attributs)
Object readObject() : reconstituer l'objet qui a été écrit par writeObject(…).
Les classes des objets <<sérialisable>> doivent implémenter l'interface
java.io.Serializable.
130
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple de la sérialisation d'objets
// chargement d'un objet d'un fichier
FileInputStream fin = new
FileInputStream("c:/biblio.obj");
ObjectInputSteam oin = new
ObjectInputStream(in));
Biblioteque biblio = oin.readObject();
// on peut naviguer vers des livres et
des adhérents et exemplaires
public class Livre
implements Serializable {
String nom; String auteur;
List<Exemplaire> exemplaires;
}
public class Bibliotheque
implements Serializable {
List<Livre> livres;
List<Adhérent> adherents;
}
public class Adhérent
implements Serializable {
String nom;
}
public class Exemplaire
implements Serializable {
int no; Adhérent emprunteur;
// null signifie libre
}
131
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple: Flux de données
compressées
// From The Java Developers Almanac 1.4
// Files to include in the ZIP file
String[] filenames = new String[]{"filename1", "filename2"};
// Create a buffer for reading the files
byte[] buf = new byte[1024];
try { // Create the ZIP file
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("outfile.zip"));
// Compress the files
for (int i=0; i<filenames.length; i++) {
FileInputStream in = new FileInputStream(filenames[i]);
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(filenames[i]));
// Transfer bytes from the file to the ZIP file
int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); }
// Complete the entry
out.closeEntry(); in.close();
} // Complete the ZIP file
out.close();
} catch (IOException e) { }
132
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Manipulation de fichiers et répertoires
La classe java.io.File représente des fichiers et des
répertoires existants ou non (qui vont être créés).
Elle propose des méthodes suivantes pour manipuler les
fichiers des répertoires :
File(String pathname), File(String parent, String child)
boolean exists() boolean canRead(), boolean canWrite()
boolean delete(), boolean renameTo( File dest )
boolean isDirectory(), boolean isFile(), long length()
boolean mkdir()
File getParentFile(), File[] listFiles()
133
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 6.1 : Flux d'objets et sérialisation
On souhaite créer une application permettant aux
utilisateurs d'éditer l'information dans une
bibliothèque.
Elle accepte des commandes suivantes du clavier.
créer livre [nom] [auteur] [nombreExemplaire]
créer adhérent [nom]
emprunter [adhérent] [livre]
retourner [adhérent] [livre] [noExemplaire]
sauvegarder [nomFichier] : sauvegarder l'info sur un fichier.
charger [nomFichier] : charger l'info depuis un ficher.
arrêter : arrêter l'application
134
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 6.2 : Manipulation de fichiers et
répertoires
Créer une application qui ressemble à une console.
Elle propose les commandes suivantes pour manipuler les fichiers
et répertoires
pwd, cd [chemin complet ou relatif], cd ..
dir
mkdir [nom de répertoire],
rename [nom actuel] [nouveau nom]
move [fichier/répertoire] [chemin du répertoire destinataire].
del [nom de ficher/répertoire].
copy [fichier source] [fichier cible]
view [fichier]
visualiser sur l'écran
135
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
7. Threads et
synchronisation
La programmation concurrente,
synchronisation, wait et notify.
Problèmes producteurconsommateur, lecteur-écrivain
136
Thread
Un programme multithreads peut exécuter
plusieurs activités en
parallèle.
Ex. Application de
téléchargement : plusieurs
threads téléchargent des
fichiers en parallèle.
Un thread suit une
séquence d'instructions
137
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple : téléchargement parallèle
Thread A : charger un fichier : "A.zip"
while(p<100.00) {
[charger un bloc de données]
[afficher : fileName chargé p% ]
}
[afficher : fileName chargement complet ]
Thead B : charger un fichier : "B.zip"
Ecran :
A.zip chargé 3%
B.zip chargé 8%
A.zip chargé 5%
B.zip chargé 13%
…..
while(p<100.00) {
[charger un bloc de données]
[afficher : fileName chargé p% ]
}
[afficher : fileName chargement complet ]
138
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Définir ce que font des threads
Les classes héritant de java.lang.Thread ou
implémentant l'interface java.lang.Runable spécifient le
code que doivent exécuter des threads.
redéfinir la méthode run()
Un objet instance d'une telle classe représente un thread
Thread A :
charger A.zip
public class MonThread extends Thread {
String fileName;
public void run() { // redéfinition
// le code
}
}
Thread B :
charger B.zip
instanciation
139
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Deux façons de définir un thread
Façon 1 : Créer une classe héritant de la
classe java.lang.Thread
Façon 2 : Créer une classe implémentant
l'interface java.lang.Runnable
140
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Lancement de threads
Instanciation d'une classe définissant le thread.
Si la classe est définie de la façon 1 (Thread)
t.start();
Si la classe est définie de la facon 2 (Runable)
MonThread t = new MonThread("A.zip", "Thread A");
Le constructeur est utile pour passer des données qui seront manipulées par le thread
Ex. passer le nom du fichier à charger.
Créer un thread enveloppe et appeler start()
Thread enveloppe= new Thread(t, "Thread A");
enveloppe.start();
La méthode run() que vous avez définie sera exécutée par le système en activité
parallèle.
N'appelez pas vous même la méthode run() ! : Cela ne créera pas le parallélisme.
141
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple : lancement de thread chargeur de
fichiers
public class MonThread extends Thread {
String fileName;
public MonThread(String fileName, String threadName) {
super(threadName);
this.fileName = fileName;
}
public void run() { … }
public static void main(String[] args) {
MonThread tA = new MonThread("A.zip", "Thread A");
MonThread tB = new MonThread("B.zip", "Thread B");
tA.start();
tB.start();
}
}
142
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Définir une tache périodique
Exemple d'une tache périodique
En général, une tache périodique épouse un comportement
comme suit :
Vérification de l'arrivée de nouveaux mails
while(activated) {
// faire quelque chose
try {
Thread.sleep(60000); // 60 secondes
} catch(InterruptedException e) { }
}
La méthode sleep(..) permet au thread courrant d'arrêter
l'exécution pendant un temps spécifié (en milliseconde)
143
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Synchronisation : le problème
Quel problème peut se poser si plusieurs
threads accèdent aux même données (objets)
de manière concurrente?
write(…)
donnée
(fichier)
Thread A
read()
Thread B
public File {
public byte read() { …}
public void write(byte[] b) { … }
}
144
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Synchronisation : définition de section
critique
La section critique est une section où un seul thread peut entrer à
chaque moment
Ex. Le corps des méthodes read(), write(…)
Deux approches pour définir la section critique
Façon 1 : Mettre le mot clé <<synchronized>> devant la méthode
Façon 2 : Utiliser le block : synchronized(object) { …. }
// façon 1
public File {
public synchronized byte read() {
…}
public synchronized void write(
byte[] b) { … }
}
// façon 2
// A chaque fois de lire un fichier f
synchronized(f) {
f.read();
}
145
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Synchronisation : Exemple
Trois threads tentent à exécuter les sections critiques d'un même objet en même
temps un seul thread peut y entrer à chaque moment
Thread 1
Thread 2
objet : f
Thread 3
f.write(…);
f.read(…);
f.write(…)
entrer dans la méthode
bloqué
bloqué
exécuter la méthode
bloqué
bloqué
finir la méthode
entrer dans la méthode
bloqué
exécuter la méthode
bloqué
finir la méthode
entrer dans la méthode
exécuter méthode
finir la méthode
temps
146
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Coordination entre threads : Exemple de
producteur-consommateur
On présente ici une appli multi-thread qui a besoin de la coordination
Cette appli est composée de:
Des threads "producteur" qui produisent des données et les mettent dans une
file de messages.
Des threads "consommateur" qui prennent les données de la file.
Cette appli nécessite la coordination suivante :
Les producteurs et les consommateurs ne doivent pas accéder à la file en même
temps (section critique)
Quand la file est pleine : Les producteurs doivent attendre jusqu'à ce qu'une
place dans la file est libérée.
Quand la file est vide : Les consommateurs doivent attendre jusqu'à ce qu'une
donnée est produite dans la file.
Producteurs
File de messages
Consommateurs
147
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Moniteur d'accès
Un moniteur d'accès propose des méthodes pour accéder à la file
de manière contrôlée.
Ces méthodes peuvent bloquer tant que les données ne sont pas
prêtes pour y accéder.
public class Moniteur {
private List file = new Vector(); // file de messages.
public synchronized void Moniteur(int capacity) { … }
// créer un moteur pour une file d'attente de capacité spécifiée
public synchronized void put(Object o) { … }
// déposer une donnée. bloquer si la file est pleine.
public synchronized Object take() { … }
// prendre une donnée. bloquer si la file est vide
}
// producteur
while(…) {
moniteur.put(o);
}
// consommateur
while(…) {
System.out.println( moniteur.take() );
}
148
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les méthodes wait(), notify(), notifyAll()
Le moniteur d'accès a une responsabilité de bloquer/ débloquer les threads
Les producteurs
Les consommateurs
Quand la file est vide : Bloquer
Quand il existent des données dans la file : Débloquer.
Le moniteur d'accès contrôle le blocage/ déblocage grâce aux méthodes :
void wait() throws InterruptedException : Suspendre (bloquer) le thread courrant
Quand le file est pleine : Bloquer
Quand il existent des places libres : Bébloquer
Lors que le thread est suspendu, il laisse les autres threads entrer dans la section critique
void notify() : Réveiller (débloquer) un des threads qui ont été suspendus
void notifyAll() : Réveiller tous les threads qui ont été suspendus
Ces méthodes sont proposées par tous les objets Java (java.lang.Object) ☺
149
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Implémentation du Moniteur d'accès
public class MoniteurProdCons {
private List file = new Vector();
private int cap;
public MoniteurProdCons(int capacity) { this.cap = capacity; }
public synchronized void put(Object o) {
while(file.size()==cap) { // tant que la file est pleine
try { wait(); } catch(InterruptedException e){ } }
file.add(o);
notifyAll(); // notifier les consommateurs de la production d'une donnée
}
public synchronized Object take() {
while(file.size()==0) { // tant que la file est vide
try { wait(); } catch(InterruptedException e){ } }
Object o = file.remove(0);
notifyAll(); // notifier les producteurs de la libération d'une place dans la file
return o;
}
}
150
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
MoniteurProdCons: Illustration
Cons1
Cons2
Prod1
print( m.take());
Entrer dans la section critique
La file est vide, donc le thread est
suspendu
print( m.take() );
Entrer dans la section critique
La file est vide, donc le thread est
suspendu
m.put(o1);
Entrer dans la section critique
La file devient { o1 }, Les threads
suspendus sont notifiés
Finir la méthode
Réveiller
Réveiller
Rentrer dans la section critique
Attendre de rentrer dans la section
critique
L'objet o1 est retirer de la file et
affiché, la file devient vide
Finir la méthode
temps
Rentrer dans la section critique
La file est encore vide, donc le
thread est suspendu à nouveau
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
151
Exemple de lecteur-écrivain
L'appli lecteur-écrivain est un autre exemple de la coordination
entre les threads.
Elle est composée de
Un ensemble de threads qui peuvent lire et écrire des données.
Des lectures concurrentes sont permises
Une écriture est exclusive d'autres lectures et écritures.
Lecteur 1
Ecrivain 1
byte[1000] tableau
Lecteur 2
Ecrivain 2
152
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Moniteur d'accès lecture-écriture
public class MoniteurTableau {
public synchronized void acquireReadLock() { … } // demander le droit de lecture,
bloquer si le tableau est en écriture par un autre thread.
public synchronized void acquireWriteLock() { … } // demander le droit d'écriture,
bloquer si le tableau est en lecture/écriture par d'autres threads
public synchronized void releaseReadLock() { … } // indiquer la fin de lecture
public synchronized void releaseWriteLock() { …} // indiquer la fin d'écriture
public byte read(int index) { … }
public void write(int index, byte b) { … }
}
// lecteur
Moniteur m = …;
m.acquireReadLock();
for(int i=0, i<1000; i++ ) {
byte b = m.read(i); …
}
m.releaseReadLock();
// écrivain
Moniteur m = …;
m.acquireWriteLock();
for(int i=0, i<1000; i++) {
m.write(i, (byte)2);
}
m.releaseWriteLock();
153
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Implémentation du moniteur
public class MoniteurTableau {
Set lecteurs = new HashSet(); // la liste des lecteurs en cours
Thread ecrivain = null; // l'écrivain en cours
public synchronized void acquireReadLock() {
// attendre jusqu'à ce que le tableau ne soit pas en écriture par un autre thread
while(ecrivain !=null) { try { wait(); } catch(InterruptedException e){ } }
lecteurs.add(Thread.currentThread()); // inscrire un nouveau lecteur dans la liste
}
public synchronized void acquireWriteLock() {
// attendre jusqu'à ce que le tableau ne soit ni en lecture ni en écriture par les autres threads
while(ecrivain!=null || ! lecteurs.isEmpty() ) {
try { wait(); } catch(InterruptedException e){ } }
ecrivain = Thread.currentThread(); // inscrire l'écrivain en cours
}
public synchronized void releaseReadLock() {
lecteurs.remove(Thread.currentThread() ); // enlever ce lecteur de la liste
notifyAll(); // notifier les écrivains en attente
}
public synchronized void releaseWriteLock() {
ecrivain=null; // indiquer qu'il n'existe plus d'écrivain en cours.
notifyAll(); // notifier les lecteurs/ écrivains en attente
}
… // implémentation des méthodes read(…), write(…)
}
154
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sémaphore
Un sémaphore est un moniteur d'accès qui maintient N jetons.
Un thread peut prendre un jeton du sémaphore et puis le rendre au
sémaphore
Lors que aucun jeton n'est libre, un thread demandeur de jeton sera
bloqué jusqu'à ce qu'un jeton soit libéré.
La classe "sémaphore" ressemble à ceci:
public class Semaphore {
public Semaphore(int n) { … } // constructeur, créer un sémaphore de 'n' jetons.
public void acquire() {… } // prendre un jeton, bloquer si aucun jeton n'est libre
public void release() { … } // rendre un jeton, et réveiller les threads en attente
}
A vous d'essayer
Ecrire le code de la classe Semaphore
155
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Package java.util.concurrent
(Java 1.5)
Java 1.5 propose maintenant les classes
utilitaires pour manipuler la coordination entre
les threads
java.util.concurrent.ArrayBlockingQueue
: similaire
au moniteur producteur-comsommateur présenté
Methodes : void put(Object o); Object take();
java.util.concurrent.locks.ReadWriteLock
:
similaire au moniteur lecture-écriture présenté.
java.util.concurrent.Semaphore
156
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 7.1 Producteur-consommateur
Illustrer la coordiation de thread dans une application de producteurconsommateur
Créer une file de messages de capacité 5.
Créer 2 producteurs (P1, P2) et 2 consommateurs (C1, C2)
P1 émet un par un des objets Integer {1, 3, 5, 7, 9 } dans la file, et P2,
{2, 4, 6, 8, 10}. A chaque production, le producteur affiche le message :
C1 et C2 prennent chacun 5 objets de la file. A chaque consommation,
le consommateur affiche le message :
[P1/P2] émet [objet]
[C1/C2] reçu [objet]
NB. P1 et P2 devraient être instances de la même classe
<<Producteur>>. Comment peut-t-on configurer ces composants pour
qu'ils puissent émettre différents objets?
Expliquer le résultat affiché
157
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 7.2 : Lecteur écrivain
Illustrer la coordination de thread dans une application de lecteur-écrivain
Compléter la classe MoniteurTableau.
Créer le scénario de test avec 2 lecteurs (L1, L2) et 2 écrivains (E1, E2).
Afin de mieux illustrer le parallélisme, on retarde la durée de la lecture/ écriture
du tableau. C'est-à-dire que l’on fait dormir le thread pour une durée d'une
milliseconde à chaque fois qu’un octet est lu ou écrit. Plus précisément, on
ajoute l'instruction suivante entre la lecture/écriture de chaque octet :
try { sleep(1); } catch(InterruptedException e) { }
L1 et L2 affichent le message
<<[L1/L2] read lock acquired>> après l'appel à acquireReadLock(), et
affiche <<[L1/L2] releasing read lock>> avant l'appel à releaseReadLock().
E2 et E2 affichent les messages similaires
Expliquer le résultat affiché.
158
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 7.3 : Téléchargement de fichiers en
parallèle
Créer une application permettant de télécharger des
fichiers spécifiés avec URLs en parallèle
Utiliser la classe java.net.URL pour obtenir InputStream
Utiliser la méthode lecture bloquante - int read() [] - pour
lire une donnée octet par octet. Chaque block de 200
octets lus, afficher ce message :
[nom de thread] : 200 octets lus.
Créer un scénario de test avec 3 threads
Question : Si on utilise un seul thread pour télécharger 3
fichiers, l'application sera-t-elle plus ou moins rapide?
159
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
8. Manipulation des
documents XML avec Java
160
XML (eXtensible Markup Language)
Recommandation W3C
Un document XML représente des données structurées sous forme
d'un arbre.
Ex. représentation d'un livre avec XML
Interopérabilité
<?xml version="1.0" encoding="UTF-16"?>
<book>
<booktitle> Learning Java and XML </booktitle>
<chapter>
<number> 1 </number>
<title> Introduction </title>
<content> ……. </content>
</chapter>
<chapter> …. </chapter>
…
</book>
161
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les technologies XML
Manipulation de base de documents XML : DOM, SAX
Vérification du contenu de documents XML : DTD, Schéma XML
Transformation de documents XML vers d'autres documents: XSLT
Liaisons entre documents XML : XLink, XPointer
Requête sur documents XML : XQuery
Echange et traitement de documents XML dans les systèmes
réparties : Web Services
Applications spécifiques aux domaines :
Quelques formats standards de documents XML
SMIL (Synchronized Multimedia Integration Language)
MathML (Mathematical Markup Language)
ICE (Information and Content Exchange)
…
Plus d'info : http://www.w3c.org
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
162
Prolog XML
Le prolog prend la forme :
<?xml version="1.0" encoding="UTF-16"?>
Il se localise au début du document XML
Le document doit être encodé correctement d'après la déclaration dans le prolog
Valeur par défaut : UTF-8
Ex. : Ces deux documents doivent être encodés différemment dans le flux d'octets !
<?xml version="1.0" encoding="UTF-16"?>
<book> …
</book>
<?xml version="1.0" encoding="UTF-8"?>
<book> …
</book>
163
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Un document XML est un arbre des
balises
Les balises sont nommées.
Les balises ouvrante et fermante
Ex. <book> some content…</book>
On peut y mettre des sous balises.
Si entre les deux balises est vide on peut utiliser la forme
courte
Ex. <book>, <title>, <number>
Ex. <book></book> <book/>
Les balises doivent être bien formées (ouverture/ fermeture)
Ex. <book> <name> </book> </name> Mal formé
164
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Choix entre sous balise et attributs
Utilisation de sous balises
<?xml version="1.0"?>
<message>
<to>[email protected]</to>
<from>[email protected]</from>
<subject>XML Is Really Cool
</subject>
<text> How many ways is XML cool?
Let me count the ways... </text>
</message>
Utilisation des attributs
<?xml version="1.0"?>
<message
to="[email protected]"
from="[email protected]"
subject="XML Is Really Cool">
<text> How many ways is XML cool?
Let me count the ways... </text>
</message>
165
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Des textes entre des balises
<?xml version="1.0" encoding="ISO8859-1" ?>
<message> (retourne de ligne)
(tab) <to>[email protected]</to> (retour de ligne)
(tab) <from>[email protected]</from> (retour de ligne)
(tab) <subject>XML Is Really Cool</subject> (retour de ligne)
(tab) <text> How many ways is XML cool? Let me count the ways... </text>
(retour de ligne)
</message>
Lors de la manipulation de documents XML, on évite de traiter des textes non
significatifs (retour de lignes, tab etc)
En terminologie XML, ces textes sont appelés "PCDATA" (Parsed Character Data)
Ils ne peuvent pas contenir ces caractères : < > ' "
A replacer :
< par <
> par >
& par &
' par ' " par "
166
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
D'autres caractères
Caractères non parsé
(CDATA)
On
peut mettre n'importe
quel caractère entre
<![CDATA[ et
]]>
Des commentaires
<!--
This is a comment -->
<script>
<![CDATA[
function matchwo(a,b) {
if (a < b && a < 0) then {
return 1
} else {
return 0 } }
]]>
</script>
167
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Espace de nom (<<namespace>>)
XML
Comment distinguer deux balises portant le même nom?
xmlns:ns1="http://mydefinition/person" …..
<ns1:name>John Smith</ns1:name>
xmlns:ns2="http://my-domain/map/street" …..
<ns2:name>Wall street</ns2:name>
Un namespace est défini par un URI
: person name
: street name
Solution: utiliser le namespace
<name>John Smith</name>
<name>Wall street</name>
Ex. http://:mydefinition/person, http://my-domain/map/street
Un namespace est référencé par un alias
Ex. ns1, ns2
168
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'un document XML avec des
namespaces
<f:table
xmlns:f="http://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
169
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Grammaire de documents XML
<book>
<booktitle> Learning Web Services </booktitle>
<birthday>12-01-1982</birthday>
<chapter>
<number> 1 </number>
<title> What are Web Services? </title>
<content> ……. </content>
</chapter>
…
</book>
Est-ce
correct?
Besoin de définir quelles balises sont permises.
170
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Grammaire de documents XML :
Deux approches
DTD
Simple
Un
DTD peut être mis au début du document XML
Schéma XML
Plus
puissant, de plus en plus utilisé.
Un schéma XML est lui-même un document XML.
171
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Un exemple de DTD
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to
(#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
172
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Un exemple de Schéma XML
<?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xsd:element name="note" type="notetype"/>
<xsd:complexType name="notetype">
<xsd:sequence>
<xsd:element name="to" type="xsd:string"/>
<xsd:element name="from" type="xsd:string"/>
<xsd:element name="heading" type="xsd:string"/>
<xsd:element name="body" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
173
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Manipulation de documents XML en
Java
Manipulation de documents XML
Analyser le contenu des documents.
Construire un document
W3C propose deux APIs pour manipuler les documents
Java
Vérification du contenu, extraction d'information
DOM (Document Object Model)
SAX (Simple API for XML)
Ces APIs ont été portées sur la plateforme Java
Packages: org.xml.sax, org.w3c.dom
174
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
8.1. SAX (Simple API for
XML)
175
SAX
Programmation dirigée par événements
Evènements :
start A
start H
start G
…
end A
Document
XML
Traitement
Parseur
176
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple d'événements générés
<?xml version="1.0"?>
<book>
<booktitle> Learning Java and
XML </booktitle>
<chapter>
<number> 1 </number>
<title> Introduction </title>
<content> ……. </content>
</chapter>
<chapter> …. </chapter>
…
</book>
start book,
start booktitle,
start chapter,
start number, end number,
start title, end title,
start content, … end content,
end chapter,
….
end book
177
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Le parseur : org.xml.sax.XMLReader
Méthodes pour configurer les traiteurs
d'événement.
void
setContentHandler(ContentHandler handler)
Méthode pour commencer le parcours du
document
parse(org.xml.sax.InputSource input) throws
IOException, SAXException
void
L'objet InputSource peut être construit en enveloppant l'objet
java.io.InputStream ou java.io.Reader.
178
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interface org.xml.sax.ContentHandler
On implémente l'interface ContentHandler pour
traitement des éléments.
Les méthodes suivantes seront appelées lors du
parcours d'un document XML :
Début et fin du document
Début et fin de chaque élement
void startElement(String namespaceURI, String localName,
String fullName, Attributes atts)
void endElement(String namespaceURI, String localName,
String fullName)
Détection du texte entre des balises
void startDocument()
void endDocument()
void characters(char[] ch, int start, int length)
…
179
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Interface org.xml.sax.ContentHandler
(en plus de détails)
startElement(…) et endElement(…) : Les significations de ses paramètres
String namespaceURI : URI de l'espace de nom
(ex. http://www.w3schools.com/furniture)
String localName : le nom de la balise sans l'espace de nom
(ex. table, name, width, length)
String fullName : le nom complet
(ex. f:table, f:name, f:width, f:length)
Attributes atts [pour startElement(…)] : une liste des attributs de cette élément. On peut
consulter cette liste via l'API de org.xml.sax.Attributes
void characters(char[] ch, int start, int length)
Les caractères sont localisés dans le tableau <<ch>>. Ils commencent à l'index <<start>> et
ont pour longueur <<length>>
Pour obtenir un String, on peut faire :
String s = new String(ch, start, length);
// on obtient "African Coffee Table", "80", ou "20"
<f:table xmlns:f="http://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
180
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Localisation des balises dans le
document
Le parseur passe l'objet Locator au ContentHandler.
Lors que le ContentHandler reçoit un événement, il
demande la localisation de la balise concernée au
Locator
1: setDocumentLocator(locator)
Parseur
2:
startElement(…)
Locator
ContentHandler
3: getLineNumber()
getConsumeNumer()
181
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Traitement d'erreurs
XMLReader génère des erreurs lors du parcours du document
methode void parse(org.xml.sax.InputSource input) throws IOException,
SAXException
Les erreurs peuvent être :
Caractères non valides trouvés.
Document XML mal formé (manque de balises ouvrant / fermant)
Problèmes de E/S (IOException)
Si les erreurs sont détectées, le parseur arrête le parcours du document et
jette une exception.
On peut afficher plus de détails d'erreurs comme suit
} catch (SAXParseException spe) {
System.out.println("\n** Parsing error" + ", line " + spe.getLineNumber()
+ ", uri " + spe.getSystemId());
System.out.println(" " + spe.getMessage() );
} catch (Exception e) {
e.printStackTrace();
}
182
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Arrêt du parcours
Arrêter le parcours d'un document XML, c'est utile dans les cas suivants :
Les méthodes de ContentHandler offrent le moyen de jeter des exceptions
On trouve une erreur, donc inutile de parser plus loin
On trouve une information qu'on recherche dans le document, puis on souhaite
arrêter le parcours.
startElement(..), endElement(..), characters(..) throws SAXException.
Lors que ContentHandler jette une exception, le parseur va arrêter le
parcours du document et ensuite jeter une exception par la méthode
parse(…)
parse(...)
Appli
évènement
Parseur
SAXException
ContentHandler
SAXException
183
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Spécification de l'implémentation du
parseur SAX
L'API SAX est un ensemble d'interfaces. Elle peut donc avoir différentes
implémentations.
La classe org.xml.sax.helpers.XMLReaderFactory permet d’instancier un
objet XMLReader avec une classe d’implémentation particulaire
static XMLReader createXMLReader() : utiliser la propriété Systeme
"org.xml.sax.driver" pour identifier l'implémentation.
static XMLReader createXMLReader(String className) : créer une instance de
la classe d'implémentation spécifiée.
NB. Les propriétés système peuvent être configurées de 2 façons
Ligne de commande (lors de lancement de l'appli)
Ajouter –D[propriété]=[valeur]
En exécution
java.lang.System.setProperty("property1", "valeur1");
184
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Récapitulatif : étape à suivre
Créer une XMLReader
XMLReader
r=
XMLReaderFactory.createXMLReader();
Spécifier le ContentHandler
r.setContentHandler(monContentHandler());
Parser
r.parse(inputStream);
185
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 8.1 SAX
Yahoo! fournit un service de recherche web retournant le résultat en
format XML
Exemple d'une requête au Yahoo! Web Search
http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=Yaho
oDemo&query=java+xml&results=100
Examiner le document XML retourné.
Ecrire un programme permettant de filtrer les résultats plus récents
d'une date spécifiée (D'après la balise <ModificationDate>).
Afficher toute info sur les résultats retenus.
NB. La date de modification est représentée par une long
Modifier le programme précédent pour qu'il arrête le parcours du
fichier une fois que 10 résultats sont retenus.
186
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
8.2. DOM (Document
Object Model)
187
DOM
L'API DOM permet de naviguer dans un arbre
XML et le modifier
Navigation
Modification
Document
XML
Construction
d'un arbre
Document
XML
Programme
Sérialisation
188
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Les nœuds dans un arbre XML
Document : le nœud racine.
Il contient un fils unique de type Element
Element : une balise XML
Il peut contenir des Eléments fils, des Attributs et des Textes
Attr : des attributs dans les Eléments
Text, CDATASection, Comment : des nœuds représentant
PCDATA, CDATA, et des commentaires, localisés entre des balises
Les Texts peuvent être des retours de ligne, des tabs.
Node : un nœud générique
Document, Element, Attr, Text, CDATASection, et Comment héritent de
Node.
189
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Construction d'un arbre
La class javax.xml.parsers.DocumentBuilder
permet de construire un arbre.
Un DocumentBuilder peut-etre obtenu par le factory
Un arbre est accessible à partir de l'objet
org.w3c.dom.Document
DocumentBuilderFactory.newInstance().newDocumentBuil
der()
Le DocumentBuilder propose les méthodes :
Document parse(InputStream in) : créer un arbre à partir
du flux XML
Document newDocument() : créer un arbre vide
190
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Navigation
Document d = documentBuilder.parse(inputStream);
// obtenir la balise racine.
Element root = d.getDocumentElement();
// obtenir le nom de la balise
root.getName()
// obtenir des attributs dans une balise
NamedNodeMap attMap = root.getAttributes();
for(int i=0; i<attMap.getLength(); i++) {
Attr a = (Attr) attMap.item(i);
System.out.println( a.getName() +" : " +a.getValue() );
}
String value = root.getAttribute("att1") //Une autre façon
// obtenir des fils (Element, Text, CDATASection ou Comment )
NodeList nodeList = root.getChildNodes();
for(int i=0; i< nodeList.getLength(); i++) {
Node n = nodeList.item(i);
if(n instanceof Element) { …. }
// sinon n peut être instance de Text, CDATASection ou Comment
}
191
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Navigation
On peut également monter dans l'arbre
Element
parent = (Element)
elem.getParentNode();
On peut naviguer d'un élément vers le
Document
Document
doc = elem.getOwnerDocument();
On peut naviguer
192
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Modification d'un arbre
// le document permet de créer des Element, Text, CDATASection, et
commentaire
Document doc = …;
Element elem = doc.createElement("message");
Text text = doc.createTextNode("mon texte");
// ajouter ou supprimer un attribut dans une balise
elem.setAttribute("attr1", "valeur1");
elem.removeAttribute("attr2");
// ajouter ou supprimer un fils (Element/Text/CDATASection/Comment)
dans un Element
elem1.appendChild(fils);
elem1.insertBefore(nouveauFils, refFils);
elem1.removeChild(fils);
193
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Exemple : construction d'un arbre
Document doc = documentBuilder.newDocument();
Element message = doc.createElement("message");
message.appendChild(root);
Element to = doc.createElement("to");
message.appendChild(to);
Text toText = doc.createTextNode("[email protected]");
to.apprendChild(toText);
Element from = doc.createElement("from");
message.appendChild("from");
….
194
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Sérialisation d'un arbre
La classe javax.xml.transform.Transformer
permet d'écrire un arbre XML vers un texte.
public static void write(Element root, OutputStream out) throws Exception {
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
DOMSource domSource = new DOMSource(root);
transformer.transform(domSource, new StreamResult(out));
}
195
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Spécification de l'implémentation de
DOM
Comme SAX, l'API DOM est un ensemble
d'interfaces. Il peut donc avoir différentes
implémentations.
La classe
javax.xml.parsers.DocumentBuilderFactory
permet d’instancier un objet DocumentBuilder avec
une classe d’implémentation particulaire.
System.setProperty(
"javax.xml.parsers.DocumentBuilderFactory ",
"[une classe d'impléménation]");
DocumentBuilder builder = new
DocumentBuilderFactory().newInstance().
newDocumentBuilder();
196
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Récapitulatif :
analyser un document XML
Obtenir DocumentBuilder
DocumentBuilder
builder =
DocumentBuilderFactory().newInstance().new
DocumentBuilder();
Parser un document XML
Document
d = builder.parse(inputStream);
Naviguer dans l'arbre
197
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Récapitulation :
écriture d'un document XML
Obtenir DocumentBuilder
DocumentBuilder
builder =
DocumentBuilderFactory().newInstance().newDocum
entBuilder();
Créer un arbre vide
Document
d = builder.newDocument();
Créer des fils et les mettre dans l'arbre
Sérialiser l'arbre
write(rootElement,
outputStream);
198
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Comparaison entre SAX et DOM
SAX
Traitement par événements : les traiteurs d'événements sont appelés
par le parseur.
Capable de traiter un très grand document : le document n'est pas
gardé dans la mémoire en intégralité. ☺
Pas possible de revenir sur les éléments du passé. DOM
Traitement par navigation : un arbre est d'abord construit. Ensuite, le
programme y navigue.
Pas optimal pour le grand document : le document doit être
intégralement chargé dans la mémoire. Possible de naviguer dans tous les sens. ☺
199
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
TP 8.2 DOM
Modifier l'appli de bibliothèque (TP 6.1) pour supporter la
sauvegarde et le chargement de données en format XML
comme suit :
<?xml version="1.0"?>
<Bibliotheque>
<Livre nom="…" auteur="…">
<Exemplaire no="1" emprunteur="adherent1" />
<Exemplaire no="2" />
</Livre>
….
<Adherent id="adherent1" name="Jennifer Lopez" />
…
</Bibliotheque>
200
Programmation Orientée Objet, université Paris X, Prawee Sriplakich
Téléchargement