La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Programmation Objet et JAVA Phelma 2012 1. Organisation du cours z4 cours de 2h yJava, la notion dObjet et de Classes yLhéritage et le polymorphisme yLes.

Présentations similaires


Présentation au sujet: "Programmation Objet et JAVA Phelma 2012 1. Organisation du cours z4 cours de 2h yJava, la notion dObjet et de Classes yLhéritage et le polymorphisme yLes."— Transcription de la présentation:

1 Programmation Objet et JAVA Phelma

2 Organisation du cours z4 cours de 2h yJava, la notion dObjet et de Classes yLhéritage et le polymorphisme yLes collections, Les exceptions, les fichiers yLes interfaces graphiques en Swing z7 TD de 2h ySujets donnés à lavance yUne partie du code est en général donné z1 examen de 2h zDocuments : ySite : xLe poly xLes sujets de TD ySite indispensable : x xhttp://java.sun.com/javase/6/docs/apihttp://java.sun.com/javase/6/docs/api 2

3 Java versus C zJAVA est portable sans recompilation sur toutes les plates formes (processeur/OS) yPC, Mac, yPDA, telephone, etc… zMême syntaxe, même structure de contrôle que C et C++ zPrincipales différences yPas de variables globales yPas de préprocesseur #define, #include #ifdef yPas de pointeurs yLe main est une fonction interne à une classe yC++ : Pas de surcharge des opérateurs yC++ : Pas d'héritage multiple zNombreuses bibliothèques standard yRéseau,Système, thread yGraphisme, Interface utilisateur, Multimédia yE/S, chaînes et expressions régulières` yRMI : applications réparties sur plusieurs machines ySecurité, cryptographie yBase de données, xml 3

4 Types de base zLangage fortement typé comme C++ zhuit types de base Type TailleValeur int 4 bytes à ( 231) short 2 bytes à long 8 bytes 263 byte 1 byte -128 à +127 float 4 bytes +/- ( 1, à ) double 8 bytes +/- ( 4, à 1, ) char 2 bytes caractères (internationaux) boolean true or false zValeurs extrémales par Type.MAX_VALUE, type.MIN_VALUE ychar c = Byte.MAX_VALUE 4

5 POO et UML Notions de base 5

6 Concept de classe : le point 2D zProblème posé yDéfinir les outils nécessaires pour un logiciel de géométrie tel que cabri ou pour un logiciel de dessin yExemple : définir la symétrie centrale et les translations et homothéties sur des points dans le plan cartésien zQuest ce quun point du plan zDéfinition statique : ce sont les champs ou attributs yUne entité comportant 2 coordonnées xabscisse xordonnée zQue doit on pouvoir faire avec : ce sont les méthodes yEntrées/sorties xLe créer : mettre des valeurs dans les coordonnées xLafficher : ecrire les valeurs à lécran yLutiliser pour résoudre un problème xTranslation dun vecteur donné xHomothétie par un facteur k xTrouver le symétrique dun point 6

7 class point Le point 2D en procédural ou en objet 7 Structure point avec champs x et y Fonctions void affiche (point) void translate(point*, double,double) point homothetie(point, double) point symetriecentrale(point) Fonctions void affiche (point) void translate(point*, double,double) point homothetie(point, double) point symetriecentrale(point) Attributs x et y Méthodes void affiche () void translate(double,double) point homothetie(double) point symetriecentrale() Méthodes void affiche () void translate(double,double) point homothetie(double) point symetriecentrale() zEn C, pas de liens entre les fonctions et les structures de données quelles manipulent zExemple : on peut utiliser affiche sur un entier par erreur zEn POO, on regroupe champs et fonctions au sein de la classe zil existe un lien physique entre attributs, méthodes et objets zOn ne peut pas utiliser affiche sur un int

8 En C, le point 2D et ses fonctions typedef struct Point { /* Definition des champs d'un point */ double x; double y; } POINT; /* definition des fonctions sur un point */ /* Comment afficher un point */ void affiche(POINT a) {printf("x:%lf y:%lf\n",a.x,a.y);} /* Comment translater un point */ void translate(POINT* ax, double a, double b) { ax->x += a; ax->y += b; } /* constante x point ==> point */ POINT multcste(POINT a, double k) { POINT res; res.x = k*a.x; res.y = k*a.y; return res; } /* Symetrie centrale dun point : ==> point */ POINT symetriecentrale(POINT a) {POINT res; res.x = -a.x; res.y = -a.y; return res; } Point : 2 coordonnées Quelles sont les actions réalisables sur un point ? 8

9 En C, le point 2D et ses fonctions void main() { int i; POINT p1, p2, p3; printf("Premier exemple"); p1.x=2; p1.y=8; affiche(p1); translate( &p1, 1,-6); // Attention aux pointeurs !!! affiche(p1); p2 = multcste(p1, 10.0); affiche(p2); p3=symetriecentrale(p1); affiche(p3); affiche(i); // Rien nempeche cela : il ny a aucun lien entre affiche et la structure POINT } 9

10 Exemple de classe : le point 2D public class Point { /* Definition des champs d'un point */ private double x; private double y; /* definition des methodes d'un point */ /* Constructeur : valeurs initiales d'un point */ public Point () { x = 0; y = 0; } public Point (double a, double b) { x = a; y = b; } /* Comment afficher un point */ public void affiche() { System.out.println("Abcisse "+x+" ordonnee : "+y);} /* Comment translater un point */ public void translate(double a, double b) { x += a; y += b; } /* constante x point ==> point */ public Point multcste(double k) { Point res; res = new Point(this.x, this.y); // Ou Point(x,y) res.x = k*res.x; res.y = k*res.y; return res; } /* Symetrie centrale dun point : ==> point */ public Point symetriecentrale() { return new Point(-x,-y); } } Point : 2 coordonnées Comment initialiser un point : 2 possibilités Quelles sont les actions réalisables sur un point ? 10

11 Exemple dobjet : des points particuliers public class Ex1b { public static void main (String[] args){ Point p1, p2, p3; System.out.println("Premier exemple"); p1 = new Point(2,8); p1.affiche(); p1.translate(1,-6); p1.affiche(); p2 = p1.multcste(10.0); p2.affiche(); p2=null; p3=p1.symetriecentrale(); p3.affiche(); } 3 Points : p1 p2 p3 Creation de p1 Affichage de p1 11

12 POO : concepts de base zHéritage yGraphe de parenté entre des Classes yHéritage des méthodes et données qui ne sont pas à redéfinir yAjouter des nouvelles fonctionnalités à ce qui existe déjà yIsole les éléments nouveaux pour la sécurité du code existant zEncapsulation : données+méthodes+sécurité yDonnées et méthodes dans une même entité : la classe xdonnées : les informations propres à un objet, xméthodes : les actions réalisables sur/avec cet objet yObjet : instance d'une classe ySécurité Cloisonne lintérieur et lextérieur de lobjet xprivé : inaccessible de l'extérieur de la classe ou de lobjet xpublic : ce qui l'extérieur à le droit d'utiliser yRéutiliser xsans connaître le fonctionnement interne xSans risquer de modifier ce qui est fait zPolymorphisme : une même méthode prend plusieurs formes yUne méthode est typée par ses paramètres. Le même nom est utilisable par plusieurs classes ou type de données yQuand on utilise une classe donnée, elle sait quelle est la bonne fonction à utiliser pas de test de type en POO. z1 programme ; 1 ensemble dobjets qui senvoient des messages 12

13 Conception, Modèles et Diagrammes en POO UML : Unified Modeling Langage Langage graphique de modélisation de projet informatique orienté objet : 1.Définition des classes/attributs et des méthodes (modèle statique) 2.Définition des aspects dynamiques et temporels (modèle dynamique). Le modèle statique permet de structurer les besoins de lutilisateur du logiciel : diagramme use-cases de structurer les attributs et les méthodes en les répartissant dans des classes, reliées entre elles par des liaisons de trois types : héritage, agrégation, relation : diagrammes dobjets, de classes, De structurer lapplication en terme de modules (diagramme de composants) et de matériel utilisé (diagramme de déploiement) Le modèle dynamique décrit le comportement dynamique et temporel du système : Structurer les interactions entre objets (diagramme de collaboration) et leur séquencement temporel, ie ordre d'exécution des méthodes (diagramme de séquence) Spécifier les séquences detats possibles des objets (automates) : diagramme detat-transition 13

14 Diagramme de classe : UML Nom de la classe + : public # : protégé - : private méthodes Attributs ou champs zUne classe 14

15 Questions zFaire le diagramme de classe dun complexe zQuels sont ses attributs ? zDonnez les prototypes de 4 méthodes utiles 15

16 Notion dobjet Les classes et les objets 16

17 Les classes en JAVA zUne classe permet de définir des modèles ayant une certaine autonomie zLa classe définit la structure des objets yLes champs yles méthodes utilisables par un objet de ce type, i.e. les actions quun objet de ce type peut réaliser zSyntaxe [public] class Nom_de_ma_classe { // déclaration des champs; [public, private] type nom_champ; //déclaration de methodes; [public, private] type_retour nom_de_fonction(type nom_parametre, …) } zEn java, pas de rédéfinition des opérateurs à linverse du C++ zEn pratique, le nom dune classe commence par une majuscule zLe nom du fichier est celui de la classe contenant la fonction main ou celui de la classe public 17

18 Les objets et les variables en JAVA zUn objet = un exemple ou une entité dont le modèle (type) est une classe yOn dit aussi une instance de classe. yLa variable est une référence (pointeur constant) sur cet objet zEn Java, 3 étapes yDéfinition de la variable : Point p1; xSa durée de vie est celle du bloc yCréation et allocation de lobjet : p1= new Point(2,8); xSa durée de vie est celle de son utilisation xElle est détruite AUTOMATIQUEMENT par le garbage collector, quand elle est devenue inutile yUtilisation du point p1 : xpar exemple, appliquer affiche() à p1 : p1.affiche() xou changer la valeur de labscisse : p1.x=10; zDonc zEn java, une variable est une référence, i.e. un pointeur "masqué" zLe passage dun objet comme paramètre dune fonction permet de modifier cet objet : pas besoin de passage de ladresse zPas de pointeur, de gestion mémoire par le programmeur 18

19 Concept d'objet : exemple public class Ex1c { public static void main (String[] args){ System.out.println("Premier exemple"); Point p1=null, p2=null; // Définition p1, p2 2 8 p1 p1 = new Point(); // Creation p1 p1.x=2; p1.y=8; // On change p1 p1.affiche(); p1.affiche() p2.affiche() p1.affiche() p2 p p2 = new Point(20,80); ` p2.affiche(); p1.x = p1.x + 20; p1.y += 80; p1.affiche(); p2=null; // lobjet pointé par p2 est libre p1 } // les variables p2 et p1 sont détruites } 19

20 Notion dobjet Les attributs et les méthodes 20

21 Accès aux membres Accès aux membres dun objet : objet.champ yAttention, objet est une référence yExemple : a.x est labscisse du point a. Appeler/exécuter une méthode : objetappelant.methode(param); yCela signifie que lon exécute methode(parametres) « SUR » objetappelant yLes méthodes sexécutent sur un objet yp.affiche() signifie xOn cherche la classe de p : cest la classe Point xOn cherche si une méthode affiche() existe dans la classe Point : si elle nexiste pas, erreur de compilation « Cannot find Symbol » xOn exécute cette fonction avec un paramètre supplémentaire invisible : this, qui est lobjet sur lequel on travaille = objet appelant. Ici, this = p public void translate(double a, double b) { x = x + a; y = y + b; } Si on appelle translate avec le point p sous la forme p.translate(2,3), p.x et p.y qui sont incrémentés de 2 et 3 Comment écrire public void translate(double x, double y) 21

22 Paramètre this zDans une méthode, il y a toujours un paramètre « implicite » this, qui est lobjet sur lequel on travaille yp.translate(1,2) ==> this est une référence sur p zDonc public void translate(double a, double y) { ATTENTION !!!!! x = x + a; y = y + y; } // Quand on écrit y, est ce le paramètre de la fonction ou lattribut de p ? 22 public void translate(double a, double y) { x = x + a; this.y = this.y + y; }

23 Notion dobjet Sécurité 23

24 Accès et protection zPublic yLes membres public sont accessibles pour toutes les méthodes et fonctions du programme xOn peut lire et ecrire les champs à nimporte quel endroit dans le code xOn peut executer une méthode dans nimporte quelle lméthode zPrivate yUn membre private nest accessible que par les méthodes de sa classe ou de son package xUne méthode private peut être exécutée par une autre méthode de la classe, mais pas par celles des autres classes. xUn champ private nest accessible que par une méthode de la classe. xEn particulier, main() est une fonction qui nappartient pas à la classe Point : elle ne peut pas accéder aux champs x et y dun objet de la classe Point zPrincipe de la POO : Lobjet est responsable de son état yles membres (attributs ou méthodes) peuvent etre protégés en lecture/écriture des autres fonctions ou objets du programme. 24

25 Accès aux membres et aux méthodes (2) Lecture de 2 nombres au clavier, creation dun point … Ex6.java import java.util.*; public class Ex6 { public static void main (String []arg) {double x1, x2; Point a,b,c ; Scanner clavier = new Scanner(System.in); System.out.println("Entrer 2 reels "); x1=clavier.nextDouble(); // Lecture dun reel x2=clavier.nextDouble(); // 3,14567 :virgule a= new Point(x1,x2); // Création du point avec x1 et x2 a.affiche(); // On execute affiche sur a; ici, this = a b = new Point(3,8); b.affiche(); // On execute affiche sur a; ici, this = b b.x=x1; // Interdit car x est privé b.translate(2,6); b.affiche(); a.translate(b); a.affiche(); c = a.multcst(2.); c.affiche(); } 25

26 Accès et protection Exemple :Fichier Ex7.java class Point { private double x,y;…… / / x et y ne peuvent être lus/modifiés que par des méthodes de la classe private void interdit() {x=0; System.out.println("Appel interdit hors classe"); } // interdit() ne peut être appelée que par des méthodes de la classe public void autorise() {this.interdit(); } // OK car autorise() est dans la classe // autorise() peut être appelée par des méthodes dautres classes }; public class Ex7 { public static void main (String []arg) { Point a,b ; a= new Point(1,2); a.affiche(); b= new Point(); b.affiche(); a.x=5;// Interdit car x est private b.interdit(); // Interdit car interdit() est private b.autorise(); // Autorise car autorise() est public } 26

27 Accès et protection : pourquoi ? class Fraction{ public double numerateur, denominateur; // Constructeur : jamais de denominateur nul public Fraction(double a, double b) { if (b==0) { System.out.println("Denominateur nul"); System.out.exit(1); } else {set=a; denominateur=b; } } Fraction produit(Fraction q) { // Attention si q.denominateur est nul, rien nest verifié ici numerateur *= q. numerateur; denominateur *= q. denominateur; } public String toString() { return numerateur + "/" + denominateur; } }; public class Ex7c { public static void main (String []arg) { Fraction a = new Fraction(1,2); Fraction b = new Fraction(3,4); System.out.println("b vaut " + b); b.produit(a); System.out.println("b vaut " + b); a.denominateur=0; // Cest contraire au fonctionnement de la classe, mais comme denominateur nest pas privé, cest syntaxiquement correct. b.produit(a); System.out.println("b vaut " + b); } 27

28 Classe Fraction Accesseurs et mutateurs zLe concepteur de la classe se pose la question : yQuest ce qui est utile aux autres classes et fonctions de ma classe, i.e. le monde extérieur yCe qui est utile est public, le reste, utile au fonctionnement interne de lobjet est private. yDe cette manière, « lextérieur » ne peut modifier le comportement interne et voulu par le concepteur : cest lencapsulation zEn pratique, yles champs sont souvent privés ySi besoin, autoriser la lecture du champ par un accesseur getchamp() que vous devez définir yParfois, autoriser la modification du champ par un mutateur setchamp() que vous devez définir yLes mutateurs/accesseurs peuvent etre public ou privé yToujours initialiser les champs grâce aux constructeurs yCest le concepteur qui décide et non lutilisateur de laccès possible 28 Attributs num et denum Attributs num et denum Méthodes internes à la classe void init(double,double) Méthodes internes à la classe void init(double,double) Méthodes autorisées à lextérieur main() { } main() { } Mutateurs/Accesseurs

29 Accesseurs et mutateurs 29 class Fraction{ //Attributs privés private double numerateur, denominateur; // Accesseurs et Mutateurs: public double getnumerateur(){ return numerateur; } public double getdenominateur() { return denominateur; } public void setnumerateur(double a) {numerateur=a; } // Avec ce mutateur, on est sur que jamais une fraction ne sera infinie public void setdenominateur(double a) { if (b==0) {System.out.println("Denominateur nul"); System.exit(1); } else denominateur=a; } // Methode interne à la classe, inutile pour les autres classes private void init(double a, double b){setnumerateur(a); setdenominateur(b); } // Constructeurs : on utilise la méthode privée public Fraction(double a, double b) { init(a,b); } public Fraction(Fraction q) { init(q.a,q.b); } // Meme la methode produit peut utiliser les mutateurs, avec verification automatique du denominateur. public void produit(Fraction q) { setnumerateur(numerateur*q. numerateur); setdenominateur(denominateur*q. denominateur); } };

30 Accesseurs et mutateurs 30 public class Ex7c { public static void main (String []arg) { Fraction a = new Fraction(1,2); Fraction b = new Fraction(a); System.out.println("b vaut " + b); b.produit(a); System.out.println("b vaut " + b); a.setdenominateur(0); // Cest contraire au fonctionnement de la classe, qui refuse les fractions infinies, et le programme va quitter à cet endroit. b.produit(a); System.out.println("b vaut " + b); }

31 Notion dobjet Initialisation, construction, destruction 31

32 Constructeur zConstructeur : méthode appelée automatiquement à la création d'un objet zRôle yInitialise les différentes parties de l'objet : on connaît toujours létat initial yRéalise les actions indispensable à l'état initial de l'objet yPlusieurs manières d'initialiser un objet Surcharge possible i.e. plusieurs constructeurs de même nom xConstruire un point à partir de 2 réels xConstruire un point à partir de rien xConstruire un point à partir dun autre point zSyntaxe yFonction de même nom que la classe, comme en C++ zAttention yPar défaut, java ajoute un constructeur sans paramètres yQuand on définit un constructeur, on ne peut plus construire des points sans utiliser un de ceux ci 32

33 Constructeur class Point { private double x; private double y; /* Constructeur : quelles sont les valeurs initiales d'un point */ public Point (double a, double b) {System.out.println("C1"); x = a; y = b;} public Point () { System.out.println("Constructeur 2"); x = 0; y = 0; } public Point (Point a) { System.out.println("Cons 3"); x = a.x; y = a.y; } }; public class Ex4 { public static void main (String []arg) { Point a ; System.out.println("Creation de a"); a= new Point(1,2); // Création du point 1,2, constructeur 1 System.out.println("Fin xreation de a"); System.out.println("Creation de b"); Point b = new Point(); // Création du point 0,0 constructeur 2 System.out.println("Fin creation de b"); System.out.println("Creation de c"); Point c = new Point(b); // Création de C à partir de b; System.out.println("Fin creation de c"); } 33

34 Destructeur zFonction appelée automatiquement lors de la destruction des objets Prototype : protected void finalize() En C++, ~nom_de_la_classe() zEn java, très peu utilisé car vous ne gérez pas la libération de la mémoire : cest automatique, grâce au ramasse miette zGC ou ramasse miette : yRécupère automatiquement la mémoire des objets devenus inutiles et appelle la méthode finalize yOn ne sait pas quand il est appelé : on ne sait donc pas quand est utilisé le destructeur zObjets inutiles : xobjets réels alloués qui ne sont plus utilisés xDifficile à trouver ==> quand un objet est inutile, pour quil puisse etre détruit, mettre sa référence à null zEn général, yon nappelle pas le gc() directement car il peut etre tres lent ypas de destructeur 34

35 Destructeur import java.util.*; class Point { …… protected void finalize() {System.out.println("Appel au Destructeur"); } }; public class Ex5 { public static void main (String []arg) {Point a ; Scanner clavier = new Scanner(System.in); System.out.println("Creation de a"); a= new Point(1,2); // Création du point 1,2, constructeur 1 System.out.println("Fin xreation de a"); a=null; clavier.nextLine(); System.gc(); // Destruction du point a System.out.println("Creation de b"); Point b = new Point(); // Création du point 0,0 constructeur 2 } On passe dans le destructeur Ligne : System.gc() 35

36 Notion dobjet Surcharge de méthodes 36

37 Surcharge ou Polymorphisme de méthodes : zPossibilité pour une fonction ou méthode davoir un même nom si les signatures différentes ySignature : type de retour, nombre et type des paramètres yEn Java et C++, surcharge uniquement sur les paramètres yLa fonction réellement exécuter est déterminée sur la base des paramètres utilisés xEn java, il y a liaison dynamique décidé à lexecuion yAttention : xon ne peut pas surcharger uniquement sur le type de retour 37

38 Surcharge ou Polymorphisme de méthodes : class Point { private double x, y; /* Constructeur */ public Point (double a, double b) {x = a; y = b; } public Point (Point a) {x = a.x; y = a.y; } public void affiche() { System.out.println( "x:"+x+" y:"+y);} // Deux methodes de translations : A partir de 2 reels public void translate(double a, double b) { x += a; y += b; } // A partir dun point public void translate(Point p) { x += p.x; y += p.y; } }; public class Ex5 { public static void main (String []arg) { Point a= new Point(1,2); // Création du point 1,2 Point b = new Point(10,20); Point c = new Point(b); // Création de C à partir de b; b.affiche(); b.translate(1,2); b.affiche(); c.affiche(); c.translate(a); c.affiche(); } 38

39 Objets et références 39

40 Objets et référence ou le retour des pointeurs zp1 = new Point (2,3); yp1 est une référence sur un objet réel yCest donc un pointeur constant public class Ex8b { public static void main (String []arg) { Point a,b,c ; a= new Point(1,2); a.affiche(); b = a; c = new Point(a); b.affiche(); c.affiche(); a.setx(8); a.affiche(); b.affiche(); c.affiche(); } Quest ce que ce programme affiche 1 2 a b 1 2 c

41 Le passage dobjets en paramètres class Point { …. /* Cette fonction modifie son parametre meme si elle est stupide : */ void ajoutemoiap(Point p) { p.x = p.x+x; p.y += y; } public class Ex1c { public static void main (String[] args){ Point p1=null, p2=null; 2 8 p1 p1 = new Point(2,8); p1.affiche(); p1.affiche() p2.affiche() p1.affiche() p2 p p2 = new Point(20,80); ` p2.affiche(); p2.ajoutemoiap(p1); // Ici p1 est modifié à cause de ajoutemoiap p1.affiche(); p1 } // les variables p2 et p1 sont détruites } 41 zUn objet passé en paramètre dune méthode est passé par adresse et il peut être modifié par la fonction

42 Divers 42

43 Les Entrées Sorties en pratique zLire des nombres et des chaines : classe Scanner yCréer un objet de la classe scanner associé au flux de lecture voulu : le clavier yLes méthodes nextDouble(), nextInt(), nextLine() de la classe scanner permettent la lecture des réels, entiers et chaines. zAfficher : System.out.println() import java.util.*; public class Essai { public static void main (String []arg) { double x1, x2; String x; Scanner clavier = new Scanner(System.in); System.out.println("Entrer 2 reels "); x1=clavier.nextDouble(); // Lecture dun reel x2=clavier.nextDouble(); // 3,14567 :virgule System.out.println("Voici x1 : " + x1); System.out.println("Tapez une chaine"); x=clavier.nextLine(); System.out.println("Ce que vous avez ecrit : " + x); } 43

44 Méthodes existantes dans une classe zTous les classes JAVA héritent de la classe de base Object, qui contient : z Pour laffichage : toString() yDoit retourner une représentation textuelle de lobjet yElle est utilisée par System.out.println zPour les tests dégalité : equals() ya==b ne test pas si les objets a et b sont identiques mais si a et b regarde le même objet yIl faut définir le test dégalité avec la méthode equals zPour recopier un objet : clone() class Point { …… public String toString() {return("abscisse:"+x+" ordonnée:"+y);} // Avec cette methode, on peut afficher point avec System.out.println(a) public boolean equals(Point b) {return( x==b.x && y==b.y); } }; public class Ex8c { public static void main (String []arg) { Point a,b,c,d; a= new Point(1,2); b = new Point(1,2); c=new Point(1,3); d=a; System.out.println(a);// Affiche a if (a==b) System.out.println("a et b pointe le meme objet"); if (a==d) System.out.println("a et d pointe le meme objet"); if (a.equals(b)) System.out.println("a et b de contenu identique"); if (a.equals(c)) System.out.println("a et c de contenu identique"); if (a.equals(d)) System.out.println("a et d de contenu identique"); } 44

45 Résumé zUn programme objet : y1 fonction main qui démarre le programme, crée les objets et les enchainements dactions y1 ensemble de classes décrivant les capacités des données manipulées z1 classe : type de données qui rassemble des données (champs) et la manière de sen servir (méthodes) yDonnées et méthodes protégées si besoin : xpublic : nimporte quelle fonction du programme peut les modifier ou les utiliser xprivate : seules les méthodes de la classe concernée peuvent les modifier ou les utiliser yEn pratique xdonnées privées. xQue doit faire lutilisateur avec la classe que je développe ? ==> seules méthodes publiques Initialisation, affichage, addition, etc.. xAutres méthodes privées yConstructeurs : comment initialiser lobjet ? yAccesseurs et mutateurs : méthodes publiques ou privées définissant laccès en lecture/ecriture à un champ ySurcharge : plusieurs fonctions peuvent avoir le même nom, mais pas les mêmes nombres et/ou types de paramètres z1 objet : 1 instance yDéfinir la variable yCréer lobjet yDestruction de lobjet automatique quand on nen a plus besoin : pas de gestion mémoire ni pointeurs yExécuter une méthode ou fonction : objet.méthode(parametres); x x.affiche(); ou c1.add(c2,c3); xINTERDIT : affiche(x) zAucune fonction/méthode hors dune classe, aucune variable hors dune méthode zMélanger, ajouter 3 litres de jus dorange, 1 litre de vodka, et ca doit marcher !!! 45

46 Exercices.. z1. Quelle est la différence entre une classe et un objet ? z2. Écrire les accesseurs et mutateurs d'un complexe z3. Écrire le constructeur qui prend en paramètre 2 Doubles z4. Écrire la méthode qui calcule le conjugué z5. Écrire la méthode qui calcule le module z6. Écrire le main dans cette classe yIl demande 2 doubles au clavier, créé un complexe à partir des deux doubles, calcule son module et l'affiche à l'écran, mettre la partie imaginaire à zéro et recalculer le module. ySi le main est dans la classe, il y a deux fac ̧ on de mettre la partie imaginaire à zéro, si le main est dans une autre classe, il n'y en a qu'une, pourquoi ? 46

47 Notion dobjet Les classes et objets composés

48 Les points essentiels zAgrégation ou composition yConstruction zHéritage yChainage des constructeurs yProtection des attributs yRedéfinition des méthodes / Surcharge des méthodes zPolymorphisme yLiaison dynamique yClasse abstraite zHéritage multiple

49 Des objets dans les objets zUne classe Cercle yLes champs xLe point du centre : de la classe Point: Cest un lien de COMPOSITION xLe rayon : un double yLes méthodes xLa surface xLaffichage xLa translation

50 Classe Point import java.util.*; class Point { /* Definition des donnees d'un point */ private double x; private double y; /* Constructeur : 1 seule définition, les 2 autres l'appellent */ public Point (double a, double b) { setx(a); sety(b); } public Point () { this(0.,0.); } public Point (Point a) { this(a.getx(),a.gety()); } /* Accesseurs et mutateurs */ public double getx() { return x; } protected void setx(double val) { x=val; } public double gety() { return y; } protected void sety(double val) { y=val; } public void affiche() { System.out.println("Abcisse "+getx()+" ordonnee : "+gety());} /* Comment translater un point */ public void translate(double a, double b) { setx(getx()+a); sety(gety()+b); } public void translate(Point t) { translate(t.getx(),t.gety()); } /* Afficher un nombre : deux ecritures */ public String toString() { return Double.toString(x)+","+ y +" "; } public boolean equals(Point b) {return( getx()==b.getx() && gety()==b.gety()); } public Point multcste(double k) { Point res= new Point(this); res.setx(getx()*k); res.sety( gety()*k); return res; } };

51 Des objets dans les objets class Cercle { // on utilise au maximum les méthodes de Point. private Point cdg; private double rayon; public Cercle() { rayon=0; cdg= new Point(); } // Attention : créer le cdg public Cercle(Point p, double r) { rayon=r; cdg=new Point(p); } // pas cdg=p; public Cercle(double cdgx, double cdgy, double r) { rayon=r; cdg=new Point(cdgx, cdgy); } public double surface() { return (Math.PI*rayon*rayon); } public String toString() { return("Cercle de Cdg "+cdg.toString()+" et de rayon"+rayon);} //OU public String toString() { return("Cercle de Cdg "+cdg+" et de rayon"+rayon);} public void translate(double a, double b) { cdg.translate(a,b); } } public class Ex13 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Cercle c1, c2; double x1, x2,r; Point a; // Creation du cercle avec les 3 valeurs lues au clavier System.out.println("Entrer le cdg du cercle 1, puis le rayon"); c1 = new Cercle(clavier.nextDouble(), clavier.nextDouble(),clavier.nextDouble()); System.out.println("C1 : "+c1 + "de surface :"+c1.surface()); System.out.println("Cdg cercle 2"); x1=clavier.nextDouble(); x2=clavier.nextDouble(); a= new Point(x1,x2); // Création du point avec les x1 et x2 1 System.out.println("Entrer le rayon du cercle 2"); r=clavier.nextDouble(); c2 = new Cercle(a,r); System.out.println("C2 : "+c2+" de surface :"+c2.surface()); System.out.println("translation ?"); x1=clavier.nextDouble(); x2=clavier.nextDouble(); c1.translate(x1,x2); System.out.println("C1 : "+c1); }

52 Héritage Héritage simple

53 Héritage zLhéritage est un concept pour les fainéants qui exploitent le travail des autres zLhéritage permet de réutiliser ce qui a déjà été fait très simplement yLa nouvelle classe (fille) hérite dune classe existante (père) yElle possède les mêmes champs et les mêmes méthodes yOn peut ajouter de nouveaux champs et de nouvelles méthodes zLhéritage est récursif : une classe dérivée peut devenir classe de base zLes liens hiérarchiques forment un arbre : larbre dhéritage

54 Héritage : Augmenter les capacités Augmenter les capacités dun point zExemple : Ajout de la gestion de la couleur dun point : class Point { private double x, y; …………… public void translate(double a,double b) {setx(x+a); sety(y+b); } } class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a déjà x et y */ private int couleur; public PointCouleur () { // Par defaut, x et y sont nuls super(); // ATENTTION : x=0; y=0; est interdit couleur=0; } public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){return (super.toString()+ "couleur"+Integer.toString(couleur));} };

55 Héritage : Spécialiser lobjet Spécialiser les capacités dun point zExemple : Uniquement les points positifs : class Pointpositif extends Point { // on autorise que les nombres positifs public void setx (double a) { if (a>=0) super.setx(a); else System.out.println("Erreur "+a); }; public void sety (double a) { if (a>=0) super.sety(a); else System.out.println("Erreur "+a); }; }; public class Ex16 { public static void main (String []arg) {PointCouleur a,b,c ; Pointpositif d; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); c=new PointCouleur(8,9,65535); System.out.println("a "+a); System.out.println("b "+b); a.translate(2,3); System.out.println("a "+a); //c = b.multcste(5); System.out.println("c "+c); d =new Pointpositif(1,2); System.out.println("d "+d); d.translate(1,1); System.out.println("d "+d); d.translate(-3,0); }

56 Héritage : Mettre en commun zFaire des classes permettant de manipuler les cercles et les rectangles yCréer yCalculer la surface yTranslater

57 Héritage : Mettre en commun zLes cercles et les rectangles ont des points communs yLe cdg yLa creation zOn fait donc une classe « pere » qui reroupe les parties communes des cercles et des rectangles zOn peut faire encore plus !!

58 Héritage : intérêt zDéfinir explicitement les liens entre les classes yUne classe augmente ou étend les possibilités dune autre classe : on ajoute la notion de couleur yUne classe spécialise une autre classe : le point positif est un point du quart de plan x>0 y>0 yUne classe adapte le comportement dune autre classe à un besoin concret yA linverse, une classe mère regroupe des comportements communs (voir la classe forme ci dessous) yUn mélange des trois raisons précédentes zExploiter les classes existantes ySans écrire de code ySans connaître le code zGénie logiciel : organisation du développement logiciel yRegrouper les aspects (ici, champs ou methodes) communs yDéfinir les accès et les protections des structures de données yMieux conceptualiser les développements zComment ? yTrouver les relations de type « est-un » : classe dérivée yTrouver les points communs et les regrouper : classe mère

59 Héritage : ne pas confondre avec lassociation zRelation de spécialisation/généralisation ySpécialisation dune classe par rapport à un modèle de base : héritage yEx : le lien Ecran-Périphérique zRelation structurelle dagrégation yComposition dun objet par un ou plusieurs composants ou objets appartenant uniquement à cet objet yEx : Ordi possède un écran et clavier zRelation structurelle dassociation yRelation existant entre deux objets, moins forte que la précédente (non exclusive) yEx : une entreprise emploie une personne mais les objets représentant la personne et lentreprise existe séparément. zLe graphe complet pour un ordi

60 Champs hérités : zUn objet possède tous les champs de sa classe et de sa classe mère, de grand-mère… zLe nom est comme précédemment : objet.nom_du_champ yLe nom de la classe mère napparaît pas : si a est un PointCouleur : on écrit a.couleur, a.x, a.y zMais yLes protections sappliquent : les champs privés ne sont accessibles que par les méthodes de la classe où ils sont définis. Les champs x et y de Point sont privés yUn objet de la classe PointCouleur accède au champ couleur mais pas aux champs x et y sils sont private. yImportant quand vous définissez une hiérarchie de classes utilisées par dautres !!!! yTrop lourd lorsque cest un ensemble de classes cohérentes comme les Point, PointCouleur zDonc yLe mot clé protected permet laccès aux champs pour toutes les classes dérivées Le mot clé final interdit à une classe detre superclasse, à une méthode detre redéfinie.

61 Champs hérités privés : class Point { private double x, double y; …. } class PointCouleur extends Point { private int couleur; /* Les nouveaux constructeurs */ public PointCouleur () { x=y=0; couleur=0; } // INTERDIT car x et y privé public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){ return (super.toString()+ "couleur "+Integer.toString(couleur)); } }; public class Ex17a { public static void main (String []arg) { PointCouleur a,b; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); System.out.println("a "+a); System.out.println("b "+b); a.translate(2.,3.); System.out.println("a "+a); a.x=56; INETRDIT, car main nest pas une méthode de PointCouleur } zImpossible dutiliser les parties privées x et y dun point couleur sans mutateur zParfois lourd à programmer

62 Champs hérités protected : class Point { protected double x, double y; …. } class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a déjà x et y */ protected int couleur; /* Les nouveaux constructeurs */ public PointCouleur () { x=y=0; couleur=0;} // ATENTION : on peut modifier x et y public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){ return (super.toString()+ "couleur "+Integer.toString(couleur)); // super, cest la classe mere } }; class Truand extends PointCouleur { public void setx(double a) { x=a; } // Je modifie x, meme si je nai pas le code PointCouleur: contraire à la POO } public class Ex17 { public static void main (String []arg) {PointCouleur a,b; Truand c; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); System.out.println("a "+a); System.out.println("b "+b); a.translate(2,3); System.out.println("a "+a); //a.x=56; A Eviter, car main nest pas une méthode de PointCouleur c = new Truand(); System.out.println(c); //Vraiment pas recommandé; il suffit de déclarer PointCouleur comme classe finale pout etre tranquille c.setx(8); System.out.println(c); } zUtilisation directe des parties protected x et y dun point zAttention à la protection qui peut etre détournée yOn suppose que Point et PointCouleur sont écrites et on ne dispose pas du source yTruand hacke la classe Point par héritage

63 Champs hérités : conserver la protection class Point { protected double x, double y; …. } final class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a déjà x et y */ protected int couleur; …………. }; class Truand extends PointCouleur { // Interdit car classe PointCouleur est final public void setx(double a) { x=a; } } public class Ex17b { public static void main (String []arg) {PointCouleur a,b; Truand c; …. } zPour empecher nimporte quel utilisateur de modifier les champs protected, il faut interdire lhéritage zLa classe truand ne peut plus hériter de PointCouleur

64 Méthodes héritées : comment sy retrouver zUn objet possède toutes les méthodes de sa classe et de sa classe mère, de grand-mère… zLappel est comme précédemment : objet.nom_de_methode(parametres); yLe nom de la classe mère napparaît pas : si a est un PointCouleur : a.translate(2,3); zComment trouve t on la bonne méthode ? yOn cherche dans la classe de lobjet a : xsi la méthode est ici (meme nom, meme nombre et type de paramètres), on lexecute ySinon On cherche dans la classe mère de a, puis dans la classe grandmère…. zMot clé super : désigne la classe mère de lobjet ou de la classe. yPermet d'exécuter les méthodes dont on hérite yexemple : méthode toString dans la classe PointCouleur zAttention au vocabulaire yUne méthode est redéfinie dans une hiérarchie lorsquelle a le même nom et les mêmes types de paramètre yUne méthode est surchargée lorsquelle a le même nom et des types différents de paramètres

65 Méthodes redéfinies et surchargées : class Point { ….. public void translate(double a,double b) { System.out.println("Methode translate de point"); x += a; y+= b; } class PointCouleur extends Point { /* Definition des champs d'un point couleur ; on a deja x et y */ protected int couleur; /* Les nouveaux constructeurs */ public PointCouleur () { super(); couleur=0;} public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; } public String toString(){ return ("redefinie : "+super.toString()+"couleur " +Integer.toString(couleur)); } public void translate(double a,double b, int c) { // SURCHARGE : c System.out.println(" Surcharge methode translate "); super.translate(a,b); couleur += c; } }; public class Ex18 { public static void main (String []arg) {PointCouleur a,b; a=new PointCouleur(1,2,0); b=new PointCouleur(4,5,255); System.out.println("a "+a); System.out.println("b "+b); a.translate(2,3); System.out.println("a "+a); b.translate(4,8,-1); System.out.println("b "+b); }

66 Cas particulier des constructeurs zLa classe PointCouleur dérive de Point. zDonc, zlors de la construction dun PointCouleur, il faut quun constructeur de Point soit appelé, car seul Point est responsable de la construction dun point zDonc, un constructeur de PointCouleur appelle toujours un constructeur de Point ySoit explicitement xsuper(parametres) : appel explicite en PREMIERE instruction à un constructeur de Point xthis(parametres) : appel explicite en PREMIERE instruction à un constructeur de PointCouleur ySoit implicitement xAucun appel explicite: le compilateur ajoute un appel à super() en tete de constructeur. xSil ny a pas de constructeur Point(), erreur dexecution

67 Cas particulier des constructeurs (2) import java.util.*; class Point { protected double x,y; public Point (double a, double b) { System.out.println("Point : Constructeur 1"); x = a; y = b; } public Point () { System.out.println("Point : Constructeur 2"); x = 0; y = 0; } public Point (Point a) { System.out.println("Point : Constructeur 3"); x = a.x; y = a.y; } }; class PointCouleur extends Point { protected int couleur; public PointCouleur (double a, double b, int c) { super(a,b); couleur=c; System.out.println("PointCouleur : Constructeur 1"); } public PointCouleur () { System.out.println("PointCouleur : Constructeur 2"); couleur=0; } public PointCouleur (PointCouleur a) { this(a.x,a.y,a.couleur); System.out.println("PointCouleur : Constructeur 3"); } } public class Ex19 { public static void main (String []arg) { PointCouleur a,b,c; Scanner clavier = new Scanner(System.in); System.out.printf("Construction a"); a = new PointCouleur(1,2,3); System.out.printf("Construction b"); b = new PointCouleur(a); System.out.printf("Construction c"); c = new PointCouleur(); }

68 Héritage et Polymorphisme Liaison statique et dynamique

69 Héritage et Polymorphisme zPolymorphisme : même traitement pour des objets de classe différentes yInteret : même nom pour des choses identiques (clone(), toString(), translate()…) yLiaison dynamique : si x est une forme, quelle est la vraie méthode qui sapplique à x yExemple : surface() ?

70 Polymorphisme : exemple class Forme { protected Point cdg; public Forme() { cdg=new Point(0,0);} public Forme(double a, double b) { cdg=new Point(a,b);} public Forme(Point a) { cdg=new Point(a); } double surface() { System.out.println("Surface de Forme"); return 0; } void translate(double a, double b) { System.out.println("Translate de Forme"); cdg.translate(a,b); } public String toString() {return cdg.toString(); } } class Cercle extends Forme{ protected double rayon; public Cercle() { super(); rayon=0; } public Cercle(Point p, double r) { super(p); rayon=r; } // pas cdg=p; public Cercle(double cdgx, double cdgy, double r) { super(cdgx,cdgy); rayon=r; } public double surface() { System.out.println("Surface de Cercle"); return (Math.PI*rayon*rayon); } public String toString() { return ("Cercle de Cdg "+cdg.toString()+" et de rayon "+Double.toString(rayon)); } }

71 Polymorphisme : exemple class Rectangle extends Forme { protected double largeur, hauteur; public Rectangle() { super(); largeur=hauteur=0; } public Rectangle(Point p, double l, double h) { super(p);largeur=l;hauteur=h; } public Rectangle(double cdgx, double cdgy, double l, double h) {super(cdgx,cdgy);largeur=l;hauteur=h; } public double surface() { System.out.println("Surface de Rectangle"); return (largeur*hauteur);} public String toString() { return (getClass().getName()+"Rectangle "+super.toString()+" "+hauteur+" "+largeur); } } public class Ex20 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Cercle c1; Rectangle r1; Forme f1, f; c1=new Cercle(2,3,4); r1=new Rectangle(8,9,2,3); f1 = new Forme(6,7); double s1=c1.surface(); System.out.println("Surface de c1 "+s1); double s2=r1.surface(); System.out.println("Surface de r1 "+s2); double s3=f1.surface(); System.out.println("Surface de f1 "+s3); f=c1; System.out.println("Surface de f"+f.surface()); f=r1; System.out.println("Surface de f"+f.surface()); f=f1; System.out.println("Surface de f"+f.surface()); f = new Cercle(5,6,7); System.out.println("Surface de f"+f.surface()); } On connaît les classes de c1, r1,f1 Ici, on ne connaît pas la classe réelle de f Quel est le résultat ?

72 Polymorphisme : exemple (3) zConclusion yLiaison statique : lorsque la classe est connue, la fonction surface utilisée est celle de la classe de lobjet appelant. JAMAIS EN JAVA yLiaison dynamique : lorsque la classe effective est inconnue (f est une forme), le type réel de lobjet est déterminé dynamiquement (au moment de l'exécution) avant de chercher la fonction. Cest donc la fonction de la classe réelle qui est utilisée, et non celle de la classe visible yAttention, cest la notion de conversion entre classe de base et dérivée : un rectangle est une forme, mais linverse nest pas vrai.

73 Liaison dynamique, vérification statique zVérifications statiques yÀ la compilation yÀ partir du type déclaré de lobjet : la classe de cette objet doit contenir une méthode dont la signature est compatible avec lappel yOn ne connaît pas le type réel de lobjet, donc impossible de vérifier la classe effective contient une méthode correcte yLe type de la méthode est définit à la compilation en fonction des paramètres. Si Forme et ses dérivés contiennent les fonctions surface() et surface(int), cest à la compilation que lon définit si on utilisera des méthode surfe) ou surface(int) Forme a = new Forme(); a.surface();// La classe Forme doit contenir une méthode surface() Forme b = new Rect(); b.surface();// La classe Forme doit contenir une méthode surface(), car ici le compilateur ne peut pas savoir que b est un rectangle. Mais il sait que la méthode surface ne prend pas de paramètres b.surface(10);// La classe Forme doit contenir une méthode surface(int), zLexecution recherche simplement dans la classe réelle de lobjet la méthode dont la compilation a définit le choix. Forme a = new Forme(); a.surface();/lexecution execute surface() de Forme Forme b = new Rect(); b.surface();//lexecution execute surface() de Rect b.surface(10); //lexecution execute surface(int) de Rect

74 Polymorphisme et classe abstraite

75 zPeut on déterminer la surface dune forme ? zQuest ce quune forme ? yUn concept : on ne peut créer un objet de type Forme, puisque quon ne peut pas le définir complètement xLa méthode surface est impossible à écrire. Renvoyer 0 est une aberration xQue faut il faire ? zDans la classe Forme, surface est donc une méthode abstraite ySurface() doit exister dans les classes dérivées, mais on ne sait pas lécrire au niveau de forme zDe ce fait, la classe Forme est une classe abstraite yOn ne peut pas créer un objet à partir dune classe abstraite, car il nest pas complètement défini zUne classe peut hériter dune classe abstraite. Si une classe hérite dune méthode abstraite et que cette méthode nest pas redéfinie dans la classe, alors la classe est obligatoirement abstraite.

76 Polymorphisme et classe abstraite abstract class Forme { protected Point cdg; public Forme() { cdg=new Point(0,0);} public Forme(double a, double b) { cdg=new Point(a,b);} public Forme(Point a) { cdg=new Point(a); } abstract double surface(); void translate(double a, double b) { System.out.println("Translate de Forme"); cdg.translate(a,b); } public String toString() {return cdg.toString(); } } class Cercle extends Forme{ protected double rayon; public Cercle() { super(); rayon=0; } public Cercle(Point p, double r) { super(p); rayon=r; } // pas cdg=p; public Cercle(double cdgx, double cdgy, double r) { super(cdgx,cdgy); rayon=r; } public double surface() { System.out.println("Surface de Cercle"); return (Math.PI*rayon*rayon); } public String toString() { return ("Cercle de Cdg "+cdg.toString()+" et de rayon "+Double.toString(rayon)); } }

77 Polymorphisme et classe abstraite class Rectangle extends Forme { protected double largeur, hauteur; public Rectangle() { super(); largeur=hauteur=0; } public Rectangle(Point p, double l, double h) { super(p); largeur=l;hauteur=h; } public Rectangle(double cdgx, double cdgy, double l, double h) {super(cdgx,cdgy);largeur=l;hauteur=h; } public double surface() { System.out.println("Surface de Rectangle"); return (largeur*hauteur);} public String toString() { return (getClass().getName()+"Rectangle "+super.toString()+" "+hauteur+" "+largeur); } } public class Ex21 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Cercle c1; Rectangle r1; Forme f1, f; c1=new Cercle(2,3,4); r1=new Rectangle(8,9,2,3); // f1 = new Forme(6,7); double s1=c1.surface(); System.out.println("Surface de c1 "+s1); double s2=r1.surface(); System.out.println("Surface de r1 "+s2); double s3=f1.surface(); System.out.println("Surface de f1 "+s3); f=c1; System.out.println("Surface de f"+f.surface()); f=r1; System.out.println("Surface de f"+f.surface()); // f=f1; System.out.println("Surface de f"+f.surface()); f = new Cercle(5,6,7); System.out.println("Surface de f"+f.surface()); }

78 Polymorphisme et classe abstraite Un tableau de formes à dessiner ou à calculer ? public class Ex22 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Forme [] tab; System.out.println("Nombre de forme "); tab = new Forme [clavier.nextInt()]; for (int i=0; i< tab.length; i++) { switch( (int) ((Math.random()+0.5)*2)) { case 1: System.out.println(i+" est un rectangle "); tab[i]=new Rectangle(Math.random(),Math.random(),Math.random(),Math.random()); break; case 2: System.out.println(i+" est un cercle "); tab[i]=new Cercle(Math.random(),Math.random(),Math.random()); break; } for (int i=0; i< tab.length; i++) System.out.println("Surface de "+ i+" = "+tab[i].surface()); // Modifions lordre Forme f = tab[0]; tab[0]=tab[tab.length -1]; tab[tab.length -1]=f; for (int i=0; i< tab.length; i++) System.out.println( i+" = "+tab[i]); }

79 Interface

80 Une interface est un ensemble d'opérations utilisée pour spécifier un service offert par une classe. Elle peut être vue comme une classe sans attributs et dont toutes les opérations sont spécifiées mais pas définies à priori (ie vides) Elle peut être vue comme un contrat ou un modèle que doivent offrir toutes les classes qui se réclame (implémente) de cette interface public interface objetgeometrique{ public int surface(); public void translate(int, int ); }

81 Héritage Héritage multiple

82 animaux Animaux volantAnimaux nageantAnimaux courant Truites zLes animaux sont définis par une classe zLes animaux volant, nageant, courant sont eux aussi défini par une classe zUne truite est définie par une classe dérivant de nageant

83 Héritage multiple : le canard animaux Animaux volantAnimaux nageantAnimaux courant Truites Canard zUn canard vole zUn canard court (pas vite) zUn canard nage (mal) zPour respecter la notion dhéritage, il faut donc que la classe canard hérite des 3 classes volant, nageant, courant

84 Héritage multiple : problème

85 zUne truite hérite des clamps yVitesse par Nageant yPoids, nom et cdg par Nageant/Animaux zUn canard hérite des clamps yVitesse par Nageant yPoids, nom et cdg par Nageant/Animaux yVitesse par Volant yPoids, nom et cdg par Volant/Animaux yVitesse par Courant yPoids, nom et cdg par Courantt/Animaux zDonc un canard a 3 poids !!! zIl faudrait de lhéritage partagé (cela existe en C++ avec lheritage virtuel) de manière à ce que la classe Canard nhérite quune seule fois des champs poids, nom et cdg.

86 Héritage multiple : solution zSolution proposée pour le cas du canard

87 Héritage multiple zInterdit en JAVA : une classe ne peut hériter que dune seule autre classe zmais autorisé en C++ zRemplacé par la notion dinterface zQuest ce quune interface en JAVA y yprécise des comportements (des méthodes) que doivent avoir les objets qui en dérive yNe définit pas ses comportements yNa pas de champs (hormis des constantes) zUne interface peut hériter dune autre interface

88 Héritage multiple

89 class Animaux { protected int poids; protected Point cdg; public Animaux( int p) { poids=p; cdg=new Point(0,0);} public void deplace(int a, int b) {cdg.translate(a,b); } public String toString() { return ("Animal : poids "+poids+" au point "+cdg); } }; interface Volant { void vole(); public String toString(); }; interface Nageant { void nage(); public String toString(); }; interface Courant { void coure(); public String toString(); };

90 Héritage multiple class Canard extends Animaux implements Volant, Nageant, Courant { private int vitessecourse=2, vitessenage=5, vitessevole=3; private String nom; public Canard (String name, int p){super(p); nom=new String (name); } public String toString() { return ("Canard "+nom+" "+super.toString()); } public void vole() { super.deplace(vitessevole,vitessevole); } public void nage() { super.deplace(vitessenage,vitessenage); } public void coure() { super.deplace(vitessecourse,vitessecourse); } } Class Chien extends Animaux implements Courant { private int vitessecourse=10; private String nom; public Chien (String name, int p){super(p); nom=new String (name); } public String toString() { return ("Canard "+nom+" "+super.toString()); } public void coure() { super.deplace(vitessecourse,vitessecourse); } } public class Ex23 { public static void main (String []arg) { Canard a; Chien b; a=new Canard("Duffy",10); System.out.println(a); b = new Chien("Medor",50); System.out.println(b); a.vole(); System.out.println(a); a.nage(); System.out.println(a); a.coure(); System.out.println(a); b.coure(); System.out.println(b); // b.vole (); }

91 Héritage multiple zExemple : Affiche image est un composant qui permet dafficher une image yQuand j écris ce composant, je veux quil soit utilisable pour afficher facilement dautres images. Par exemple, Comment lutiliser sur les classes Fractales que vous avez faites yDans lécriture de AfficheImage, les éléments dont jai besoin sont la dimension de limage et les pixels de limage. yPour pourvoir afficher, il faut donc que limage possède ces 3 éléments : on pourrait faire de lhéritage des classes (Mendel) à afficher yMAIS Julia hérite de Fractale, qui hérite de Object. yElle ne peut pas hériter de Imagecalcul. yOn fait donc de Imagecalcul une interface

92 Tableaux zEnsemble dobjets de même type à accès direct zLes tableaux sont des OBJETS zTaille du tableau fixe, nest pas modifiable, accessible par la valeur (et pas la méthode) length: tab.length; zAccès aux éléments par tab[i] zVérification des bornes, ArrayIndexOutOfBoundsException si erreur zIndices débutant à Indices Tableau de 10 éléments tableau 0246 zCréation dun tableau en 3 étapes 3/ Utilisation : tableau [i] = 2*i 1/ Déclaration dune variable : int [] tableau ; 2/ Instanciation ou création : tableau = new int [10];

93 Tableaux (2) zEx9.java zLire la dimension au clavier, créer un tableau de nombre, le remplir et lafficher import java.util.*; public class Ex9 { public static void main(String[] arg) { int [] tableau; Scanner clavier = new Scanner (System.in); System.out.println("Nombre d'element du tableau ?"); int nb = clavier.nextInt(); tableau = new int [nb]; for (int i=0; i

94 Copie de tableaux de nombres ou partage zCopie : fonction arraycopy : la destination doit etre créée (allouée) System.arraycopy(Object src, int indsrc, Object dest, int inddest, int long) public class Ex10 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); double [] t1, t2,t3; System.out.println("Entrer le nombre de reels"); t1 = new double [ clavier.nextInt()]; for (int i=0; i< t1.length ; i++) t1[i]=2*i+1; for (int i=0; i< t1.length ; i++) System.out.print(t1[i]+" "); System.out.println(); t2=t1; t3 = new double [ t1.length ]; System.arraycopy(t1,0,t3,0,t1.length); for (int i=0; i< t2.length ; i++) System.out.print(t2[i]+" "); System.out.println(); for (int i=0; i< t3.length ; i++) System.out.print(t3[i]+" "); System.out.println(); for (int i=0; i< t2.length ; i++) t2[i]=-1; for (int i=0; i< t1.length ; i++) System.out.print(t1[i]+" "); System.out.println(); for (int i=0; i< t2.length ; i++) System.out.print(t2[i]+" "); System.out.println(); for (int i=0; i< t3.length ; i++) System.out.print(t3[i]+" "); System.out.println(); }

95 Copie de tableaux de nombres ou partage t t t2

96 Tableaux dobjets zCréation dun tableau dobjet : 2 étapes yCréer le tableau : Point [] tab = new Point [ clavier.nextInt()]; yCréer chaque objet du tableau :` for (int i=0; i< tab.length ; i++) tab[i]=new Point(2*i,2*i+1); Exemple : tableau de points public class Ex11 { public static void main (String []arg) { Point [] tab; Scanner clavier = new Scanner(System.in); System.out.println("Entrer le nombre de points"); tab = new Point [ clavier.nextInt()]; clavier.nextLine(); // Attention ; les points ne sont pas créés for (int i=0; i< tab.length ; i++) System.out.print(tab[i]+" "); System.out.println(); clavier.nextLine(); // Creation des points for (int i=0; i< tab.length ; i++) tab[i]=new Point(2*i,2*i+1); for (int i=0; i< tab.length ; i++) System.out.print(tab[i]+" "); System.out.println(); }

97 Copie légère ou profonde de tableaux dobjets zarraycopy recopie de tous les éléments du tableau yNe duplique pas les objets !!! --> partage des objets t[i] : copie légère ySI le programmeur duplique aussi les objets t[i] : copie profonde public class Ex12 { public static void main (String []arg) { Point [] tab, copie1, copie2; Scanner clavier = new Scanner(System.in); System.out.println("Entrer le nombre de points"); tab = new Point [ clavier.nextInt()]; // Creation des points for (int i=0; i< tab.length ; i++) tab[i]=new Point(2*i,2*i+1); // Pour tous les points du tableau tab for (Point a : tab) System.out.print(a+" "); System.out.println(); copie1 = tab; copie2 = new Point [tab.length] ; System.arraycopy(tab,0,copie2,0,tab.length); for (Point a : tab) System.out.print(a+" "); System.out.println(); for (Point a : copie1) System.out.print(a+" "); System.out.println(); for (Point a : copie2) System.out.print(a+" "); System.out.println(); // On met toutes les abcisses de tab a zero for (int i=0; i< tab.length ; i++) tab[i].setx(0); for (Point a : tab) System.out.print(a+" "); System.out.println(); for (Point a : copie1) System.out.print(a+" "); System.out.println(); for (Point a : copie2) System.out.print(a+" "); System.out.println(); }

98 Copie légère de tableaux dobjets tab copie1 copie1=tab arraycopy(…) copie2 zPour la copie profonde, il faut utiliser la méthode clone(). Voir plus loin sur les interfaces

99 Copie légèrede tableaux dobjets

100 Les containers Tableaux, Listes, Ensembles, Listes associatives

101 Les containers zLes structures de données classiques yListes xAccès séquentiel : premier, suivant ==> recherche lente xDynamique : nombre déléments variable dans le temps xInsertion, suppression faciles et efficace yTableaux xAccès direct xNombre déléments fixés à lavance xInsertion et suppression lentes zContainers : les structures classiques + les principaux algorithmes disponibles yStructures linéaires xListes xEnsembles, ensembles triés: éléments ne peuvent etre dupliqués xTableaux, Tableaux dynamiques yStructures associatives ou dictionnaire =Map xEléments : couple clé-valeur xExemples : (nom, n°telephone) yStructures plus complexes : tables hachage, arbres binaire, arbres balancés yMéthodes et algorithmes xAjout, suppression, appartenance, recherche xTri,

102 Les containers Classe concrete Interface

103 2 catégories de conteneurs zCollection List structure séquentielle, l'utilisateur contrôle l'ordre des éléments. ArrayList implémentation dans tableau de taille variable, accès par indice Vector toujours implémentation dans tableau … (plus vieux) LinkedList implémentation par double chaînage et pointeurs Queue FIFO, file à priorité Set (pas deux éléments identiques) HashSet ensemble non ordonné, impléménté par table de hachage TreeSet ensemble ordonné implémenté par arbre binaire de recherche équilibré (red black tree) Map ensemble associatif HashMap les clés sont un ensemble non ordonné TreeMap : item les clés sont un ensemble ordonné

104 Quelques méthodes communes aux collections Collection boolean isEmpty(); int size(); boolean add(E elt); // vrai sil est effectivement ajouté boolean remove(Object o); // vrai sil est effectivement retiré void clear(); boolean contains(Object o); zPour linstant, utiliser contains et remove avec le profil : yboolean remove(E elt); boolean remove(E elt); zMéthodes static de la classe outil Collections : des algo génériques yvoid Collections.sort(List ); yE Collections.max(Collection ); E Collections.min(Collection ); yvoid Collections.reverse(List ); zAller voir lAPI pour plus !!!

105 Quels containers choisir ? zEn général, on sait si on a besoin dune liste, dun tableau, dun ensemble, dun ensemble trié, dun dictionnaire, dun dictionnaire trié, dun arbre binaire de recherche. zOn définit un objet du type de linterface la plus générique : Collection zOn crée ensuite lobjet réel du type voulu : yLinkedlist : liste séquentielle classique avec pointeur yArrayList : liste implantée par un tableau avec accès par index rapide. On peut aussi considérer que cest un tablleau dont la taille peut varier dans le temps. yVector, à peu pres identique à ArrayList yQueue (FIFO) : file !!! yHashSet : ensemble implémenté par une table de hashage xEnsemble : une seule occurrence de chaque élément autorisé xAccès aux éléments rapide yTreeSet, : ensemble implémenté avec un arbre binaire de recherche, trié en permanence yHashMap : ensemble associatif (clé valeur) yTreeMap : Ensmble associatif trié en permanence sur la clé xAccès aux éléments rapide en log(n)

106 Les collections : les méthodes générales zMéthodes de la classe collections yboolean isEmpty() : test si le conteneur est vide yint size() : renvoi le nombre déléments du conteneur yboolean add(Object) : ajoute un élément au conteneur yboolean addAll(Collection) : ajoute tous les éléments dune collection au conteneur yboolean remove(Object) : supprime un élément au conteneur yboolean removeall(Collection) : supprime tous les éléments dune collection du conteneur yvoid clear() : supprimer tous les éléments du conteneur yboolean contains(Object) : appartenance dun élément au conteneur yObject [] toArray() : transforme une collection en tableau yIterator iterator() : définit un itérateur pour le parcours du conteneur zMéthodes statiques : algorithmes génériques yvoid sort(List) yObject max(Collections), Object min(Collections) yvoid reverse(list) yvoid rotate(collection, distance)

107 Linterface list : les méthodes zMethodes yboolean add(int index, Object o) : ajoute un élément dindice index au conteneur yObject get(int index) : obtient lobjet à lindice index du conteneur yboolean remove(int index) : supprime un élément dindice index au conteneur yboolean removeall(Collection) : supprime tous les éléments dune collection du conteneur zLinkedList yImplantation par une liste doublement chainée yAccès direct au début et à la fin yAccès séquentiel aux éléments (attention au cout des fonctions utilisant un indice) yMéthodes supplémentaires xaddFirst(), addLast(),, getFirst(), getLast(), removeFisrt(),, removeLast() zArrayList yImplantation par un tableau yAccès direct à tous les éléments yInsertion et suppression obligent à décaler les éléments

108 Collection : utilisation et iterateur zDéclarer une collection yCollection col; zCréer une collection vide (classe non abstraite : linkedList, ArrayList, Vector, …) ycol = new LinkedList (); zAjouter des éléments à la collection ycol.add(mon_nouvel_element); zUtiliser les algo génériques si besoin yCollections.sort(col); zParcourir ou traiter les collections : passer dun élément à un autre, en utilisant un code générique ==> la classe iterator permet le parcours dune collection quelconque; yDéclarer un iterateur : xIterator p; yCréer un iterateur SUR la collection à parcourir (methode iterator() de la classe Collections) xp= col.iterator(); yParcourir la collection : xp.hasNext() : y a t il encore des éléments dans la collection ? xClasse o; o = p.next() : retourne le prochain élément de la collection

109 Exemple : liste de points public class Ex24 { public static void main (String []arg) { Collection liste; // Definir une collection liste = new LinkedList (); // Créer la liste de point Point a = new Point(3,3); // Ajout des points dans la liste liste.add(a); liste.add(new Point(2,2)); liste.add(new Point(1,1)); // Parcours de la liste pour affichage for (Iterator p=liste.iterator(); p.hasNext(); ) { Point b=p.next(); // Remarquer le cast vers un Point System.out.println("Point = "+b); }

110 Exemple : tri de liste de points class PointComparable extends Point implements Comparable { public PointComparable (double a, double b) { super(a,b); } public PointComparable () { super(); } public PointComparable (PointComparable a) { super((Point) a); } public int compareTo(Object b) { Point a = (Point)b; if (getx() < a.getx()) return -1; else if (getx() >a.getx()) return 1; else if (gety() < a.gety()) return -1; else if (gety() >a.gety()) return -1; else return 0; } public class Ex24b { // Cest le meme code que precedement public static void main (String []arg) { Collection liste; liste = new LinkedList (); PointComparable a = new PointComparable(3,3); // Ajout des points dans la liste liste.add(a); liste.add(new PointComparable(2,2));liste.add(new PointComparable(1,1)); // Parcours de la liste pour affichage for (Iterator p=liste.iterator(); p.hasNext(); ) { PointComparable b; b= p.next(); // Remarquer labsence de cast vers un Point System.out.println("Point = "+b); } Collections.sort((List) liste); // methode de tri générique System.out.println("Apres le tri"); for (Iterator p=liste.iterator(); p.hasNext(); ) System.out.println("Point = "+ (PointComparable) p.next()); }

111 Exemple : liste de Formes public class Ex25 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Collection liste; liste = new LinkedList (); liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); for (Iterator p=liste.iterator(); p.hasNext(); ) System.out.println("Forme = "+ p.next()); // remarquer le cast en Forme : on doit indiquer que lobject // est une forme, mais le polymorphisme de laffichage permet // la liaisoon dynamique for (Iterator p=liste.iterator(); p.hasNext(); ) { Forme a= p.next(); System.out.println("surface de = "+a.surface()); }

112 Généricité : tableau dynamique de Formes public class Ex26 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); Collection tab; tab = new ArrayList (); // La seule chose à changer !!!!! tab.add(new Cercle(1,2,3)); tab.add(new Cercle(4,5,6)); tab.add(new Rectangle(9,8,7,6)); for (Iterator p=tab.iterator(); p.hasNext(); ) System.out.println("Forme = "+ p.next()); // remarquer le cast en Forme : on doit indiquer que lobject // est une forme, mais le polymorphisme de laffichage permet // la liaisoon dynamique for (Iterator p=liste.iterator(); p.hasNext(); ) { Forme a= p.next(); System.out.println("surface de = "+a.surface()); }

113 Parcourir une association (map) zLes entrées sont des couples clés-valeur (K,V) différents parcours possibles zDes méthodes permettent dobtenir : Ensemble des clés public Set keySet (); Ensemble des valeurs public Collection values (); Ensemble des entrées public Set > entrySet (); zMap.Entry yType des objets contenus dans l'ensemble retourné par entrySet yEnregistrement à 2 champs (paire), l'un de type K, l'autre de type V Accès aux champs par : public K getKey (); public V getValue

114 Parcourir une association (map) : exemple // déclaration et création dune association vide TreeMap map = new TreeMap (); // remplissage… map.put(" rouge ", "... définition du mot rouge..."); map.put(" vélo ", "... définition du mot vélo..."); map.put(" artichaut ", "... définition du mot artichaut... "); // parcours de lensemble des mots (= les clés) : System.out.print("ensemble des mots :"); for (String mot: map.keySet()) System.out.print(mot + ", "); // parcours de lensemble des définitions (= les valeurs) : System.out.print(« \nensemble des définitions :"); for (String def: map.values()) System.out.println(def. toString () + "; "); // parcours de l'ensemble des paires (cle, valeur) System.out.println("\nensemble des paires (mot,définition) : "); Iterator > itAssoc = map.entrySet().iterator(); while (itAssoc.hasNext()) { Map.Entry e = itAssoc.next(); String mot = e.getKey(); String def = e.getValue(); System.out.println(mot + " est défini par : " + def); }

115 MAP : tableau associatif : histogramme public class Ex29 { public static void main (String []arguments) { Map m = new HashMap (); for (String a : arguments) { Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1); } System.out.println("Nombre de mots differents "+m.size()); System.out.println("Histogramme des mots :"+m); }

116 Généricité En Java 1.5

117 JAVA 1.5 : la généricité en plus zGénéricité : ne pas tenir compte des objets réellement manipulés pour définir les structures de données et les algorithmes yExemple : supprimer le cast lors du parcours et de la récupération de lélément. Faire des listes de qqchoses valable pour tous les qqchoses zDéfinir les structures (classes) ou méthodes en fonction dun type paramétrique zExemple : des piles de nimporte quoi class Pile { private int nb; // Nombre delements utilises private E[] tab; // Attention : pas de creation des tableaux generiques ==> les passer dans le constructeur t=new E[2]; est interdit public Pile(E[] tableau) { tab = tableau; nb=0; }; public void empiler(E e) { if (nb < tab.length) tab[nb++] = e; } public E depiler() { return (nb>0 ?tab[--nb]:null); } public void afficher() { for (E e : tab) System.out.println(e); } } public class Ex27 { // pile dentiers et pile de point public static void main (String []arguments) { Pile p1= new Pile (new Integer[10]); p1.empiler(8); p1.empiler(10); p1.afficher(); Pile p2 = new Pile (new Point [8]); Point a = new Point(8,9); p2.empiler(a); p2.empiler(new Point()); p2.empiler(new Point(1,2)); p2.afficher(); }

118 Exemple : liste de Formes en java 1.5 Remarquer la boucle for Labsence de cast public class Ex28 { public static void main (String []arg) { Collection liste; // Collection de Forme liste = new ArrayList (); // tableau de Forme liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); System.out.println("Affichage par un foreach"); for ( Forme a : liste) System.out.println(a); // Pratique, nest il pas ? System.out.println("Affichage de la surface par iterateur"); for (Iterator p=liste.iterator(); p.hasNext(); ) { Forme a= p.next(); // Pas de conversion utile System.out.println("surface de = "+a.surface()); }

119 Traitement des erreurs Les exceptions

120 Exceptions zClasses et Méthodes permettant de décrire ce qui doit se passer en cas d'erreur yséparation du code normal du cas "exceptionnel » yTraitement de lerreur pas obligatoirement à proximité de lerreur ypropagation facile de l'erreur à travers les sous programmes yregroupement possible des exceptions yChaque méthode déclare les exceptions quelle est susceptible de déclencher zUne exception est créée par yLe système : IOException pour les ES, ArrayIndexOutOfBoundsException par exemple yVos méthodes : xPour lancer une exception vous meme: throw new MaclasseException(parametres) zLes exceptions sont des objets dont les classes dérivent de la classe Exception Throwable yOn y met les informations utiles au gestionnaire dexceptions ie les méthodes qui vont gérer lerreur.

121 Exceptions : classes particulières zLes exceptions sont classées en 3 classes zError : exceptions pour les erreurs systèmes comme pas assez de mémoire. En général, on ne peut rien faire, sinon quitter zRuntimeException : erreur classique, mais le compilateur noblige pas lutilisateur à déclarer que ses méthodes peuvent déclencher une exception. Pratique, mais des vérifications en moins. Toutes les exceptions arithmétiques, erreurs dindice de java sont de ce type par exemple. zException : erreur classique, mais le compilateur oblige lutilisateur à déclarer que sa méthode peut déclencher cette exception par le mot clé throws. Les exceptions générées par les Entrées sorties par exemple.

122 Exceptions : Transmettre une exception zLorsquune exception apparaît, on peut soit Retransmettre ( throws ) ou jeter lexception : ignorer et retransmettre lexception à la fonction appelante. ythrows permet de dire quune méthode peut déclencher une exception. Cest obligatoire public static void main(String[] args) throws IOException { int r; FileReader in = new FileReader(new File("rgb.txt")); while ((r = in.read()) != -1) System.out.println(" Caractere lu"+r); in.close(); } Capturer et traiter lexception ( try.. Catch)

123 Exceptions : Capturer une (ou plus) exception Capturer et traiter lexception ( try.. Catch) yOuverture dun fichier passé en paramètre de commande et affichage de ce fichier public static void main(String[] args) try { int r; FileReader in = new FileReader(new File (args[0])); while ((r = in.read()) ==-1) System.out.println(r); } catch (FileNotFoundException e) { // Fichier pas existant System.out.println("Pas de fichier "+e); e.printStackTrace(); System.exit(1); } catch (IOException e) { // Autre erreur dE/S System.out.println("Autre erreur"); }

124 Exceptions : Capturer une exception

125 Exceptions : lancer une exception zBeaucoup dexceptions sont déjà possible en java. zPour lancer une exception, on utilise le mot clé throw suivi de la création de lobjet dont la classe est celle de lexception voulue Ne pas oublier de déclarer que la méthode en question est susceptible de lancer une exception par le mot clé throws dans le prototype class Except2 { static int factorielle(int n) throws Exception { int res = 1; if (n<0){ throw new Exception(); } for(int i = 1; i <= n; i++) res = res * i; return res; } public static void main (String [] args) { int x; System.out.println("Entrez un nombre (petit):"); Scanner clavier=new Scanner(System.in); x = clavier.nextInt(); try { System.out.println(factorielle(x)); } catch (Exception e) System.out.println("Factorielle de " +x+" pas definie !"); }

126 Exceptions : créer votre exception zBeaucoup dexceptions sont déjà possible en java. Rare de créer une exception. zGestion des exceptions pour assurer que les Pointspositifs ont bien des coordonnées positives yCréer une classe Monexception dérivant de RuntimeException yDétection et lancement des exceptions dans les mutateurs setxexception(), setyexception() yLa classe MonException stocke le point dans son etat avant la tentative de coordonnées négatives ainsi que la valeur négative. yLe traitement est simplement laffichage du point et de la valeur aberrante class Monexception extends RuntimeException { private Point a; double valeur; public Monexception() {} public Monexception(Point x, double val) { a=x; valeur=val;} public String toString() { return("Exception positif "+a+"Valeur non positive "+valeur); } class Pointpositif extends Point { // nombres positifs uniquement public Pointpositif(double a, double b) {super(a,b); } public void setx (double a) { if (a>=0) super.setx(a); else throw new Monexception(this,a); }; public void translate(double a, double b) { setx(getx()+a); sety(gety()+b); }

127 Exceptions : gérer une exception zDans cet exemple, yla fonction f fait une translation, ne gère pas les exceptions et les retransmet à la fonction qui la appelée (main) qui devra traiter lerreur yLa fonction g fait une translation et gère les exceptions. La gestion de lerreur se limite ici à afficher cette erreur public class Ex38b { // f ne gère pas les exceptions, g les gère // Ici le throws nest pas obligatoire, car Monexception est Runtime public static void f(Pointpositif a) throws Monexception { System.out.println("Entree dans f qui ne gere pas les exceptions"); a.translate(-3,-5); System.out.println("Sortie de f qui ne gere pas les exceptions"); }// Remarque : on ne passe pas par sortie si exception !!! public static void g(Pointpositif a) { System.out.println("Entree dans g qui gere les exceptions"); try { a.translate(-3,-5); } catch (Monexception e) { // Que faire si point negatif ?? System.out.println("Erreur due a une exception dans g"); System.out.println("Les appels qui ont genere cette exception :"); e.printStackTrace(System.out); }

128 Exceptions : créer une exception public static void main (String []arg) {Pointpositif c,a,b; Scanner clavier=new Scanner(System.in); a = new Pointpositif(1,2); b = new Pointpositif(1,2); c = new Pointpositif(1,2); try { a.translate(-3,0); System.out.println("a "+a); } catch (Monexception e) { System.out.println("Les appels qui ont genere cette exception :"); e.printStackTrace(System.out); } clavier.nextLine(); try { // Obligatoire pour utiliser f(), sauf si main transmet exceptions f(b); } catch (Monexception e) { System.out.println("Les appels qui ont genere cette exception :"); e.printStackTrace(System.out); } clavier.nextLine(); g(c); }

129 Exceptions : créer une exception

130 Sérialisation Stocker et relire des objets dans des flots (disques ou reseau)

131 Sérialisation zSérialisation : Comment stocker et relire facilement des objets dans un fichier ou un flot zImporter java.io.* zInterface Serializable yAucune méthode, indique seulement la possibilité de sérialisation zCela implique que des informations sur la classe de lobjet sont stockés dans le flux zAttention : les objets « internes » doivent aussi être sérialisés yVoir la classe Point pour le champ cdg dans lexemple ci apres. zRien à faire : on utilise yle flux ObjectOutputStream et la méthode writeObject(object a) pour écrire ObjectOutputStream fic=new ObjectOutputStream(new FileOutputStream("Forme.dat")); fic.writeObject(a); yle flux ObjectIntputStream et la méthode readObject(object a) pour lire

132 Sérialisation class Point implements Serializable { …. // comme précédemment } abstract class Forme implements Serializable { …. // comme précédemment } class Point extends Forme{ …. // comme précédemment } class Rectangle extends Forme{ …. // comme précédemment }

133 Serialisation zExemple : liste de formes yOn crée une liste de formes yOn y met 2 cercle et 1 rectangle puis un autre cercle yOn les stocke dans un fichier : xDabord le nombre de forme xEnsuite, on parcours la liste pour les stocker une par une yOn relit ce fichier à laide dune deuxième liste public class Ex39 { public static void main (String []arg) { Collection liste = new ArrayList (); // tableau de Forme liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); liste.add(new Cercle(10,11,12)); for ( Forme a : liste) System.out.println(a); // Pratique, nest il pas ? System.out.println("Ecriture fichier des formes"); try { ObjectOutputStream fic=new ObjectOutputStream(new FileOutputStream("Forme.dat")); fic.writeObject(new Integer(liste.size())); // Nombre de formes for (Forme a : liste) fic.writeObject(a); // Ecriture des formes fic.flush(); fic.close(); // Fermeture du flux } catch (java.io.IOException e) { System.out.println("Erreur"); }

134 Serialisation System.out.println("Relecture des formes"); Collection liste2 = new ArrayList (); // tableau de Forme try { ObjectInputStream fic=new ObjectInputStream(new FileInputStream("Forme.dat")); Integer nb = fic.readObject(); // Lecture du nombre de Forme for (int i=0; i

135 Serialisation : encore mieux zUne liste est déjà sérialisable yOn stocke directement la liste dans un fichier : yOn relit ce fichier à laide dune deuxième liste public class Ex39 { public static void main (String []arg) { Collection liste = new ArrayList (); // tableau de Forme liste.add(new Cercle(1,2,3)); liste.add(new Cercle(4,5,6)); liste.add(new Rectangle(9,8,7,6)); liste.add(new Cercle(10,11,12)); for ( Forme a : liste) System.out.println(a); // Pratique, nest il pas ? System.out.println("Ecriture fichier des formes"); try { ObjectOutputStream fic; fic = new ObjectOutputStream(new FileOutputStream("Forme.dat")); fic.writeObject(liste); fic.flush(); fic.close(); // Fermeture du flux } catch (java.io.IOException e) {System.out.println("Erreur");}

136 Serialisation System.out.println("Relecture des formes"); Collection liste2 = new ArrayList (); // tableau de Forme try { ObjectInputStream fic; fic = =new ObjectInputStream(new FileInputStream("Forme.dat")); liste2=(ArrayList ) fic.readObject()); // Lecture des forme et } catch (IOException e) {System.out.println("Erreur : E/S");} catch (ClassNotFoundException e) {System.out.println("Erreur : classe inexistante");} for ( Forme a : liste2) System.out.println(a); // Affichage de la liste2 }

138 SWING zDu LEGO zMéthode de construction : yUne plaque de base yOn ajoute des briques prédéfinies par dessus zPlaque de base : Composants de haut niveau yFenêtre de base : objets Jframe, Jwindow, Jdialog, Objets JApplet zBriques prédéfinies : composants ou contrôle yboutons, textfield,etc..

139 Construire une IG en pratique zConstruire une fenetre de base (JFrame, JDialog, JApplet…) zConstruire un conteneur intermédiaire : Jpanel, JScrollPane, JSplitPane,… zAjouter des objets graphiques ou dautres conteneurs intermédiaires dans le conteneur intermédiaire zAjouter le conteneur intermédiaire à la fenetre de base zVisualiser la fenetre de base (methode setvisble(true)) zOn peut aussi construire de nouveaux objets graphiques à partir (héritant) d'autres objets sous forme de classe

140 Swing : exemple 1 import javax.swing.*; import java.awt.*; class Deuxboutons { private JFrame frame; JButton button; JLabel label; public Deuxboutons(){ frame = new JFrame("Exemple"); // La fenetre de base et son titre JPanel pane = new JPanel(); // Le panneau qui contiendra les boutons button = new JButton("Mon bouton"); //Le bouton label = new JLabel("Du texte"); // Zone texte pane.add(button); // Ajout du bouton au Panel pane.add(label); // Ajout de la zone de texte // frame.getContentPane().add(pane); Avant java 1.5 frame.add(pane); // Depuis java 1.5, un raccourci frame.pack(); // Dimensions préférées frame.setVisible(true); // Sinon, pas visible } public class Ex30 { public static void main(String[] args) { new Deuxboutons(); }

141 Swing : exemple 1 bis import javax.swing.*; import java.awt.*; class Deuxboutons extends JFrame { private JButton button; JLabel label; public Deuxboutons(){ super("ex31 : premiere interface"); JPanel pane = new JPanel(); button = new JButton("Mon bouton"); label = new JLabel("Du texte"); pane.add(button); pane.add(label); add(pane); pack(); setVisible(true); } public class Ex31 { public static void main(String[] args) { new Deuxboutons(); }

142 SWING zCouche logicielle indépendante de la plate forme physique zModèle-Vue-Contrôleur ymodèle : les données à afficher yvue : représentation graphique de ces données ycontrôleur : traite des interactions du composant avec lutilisateur yavantages xmeilleure modularité xplusieurs vues distinctes pour un même modèle xpossibilité de modifier limplémentation dun modèle (optimisation, réorganisation,...) sans rien changer aux vues et aux contrôleurs. zLook and Feel modifiable, internationalisation, zComposants de premier niveau yfille de la fenêtre de fond : objets Jframe, JFenetre, JDialog, JApplet

143 Apports de SWING zNouveaux objets et capacité accrue yImage dans les boutons yGestion des bordures de fenêtres yfenêtres de formes non rectangulaires yDouble buffering yJlist, Jtree, JTable yCopier/coller xjava.awt.datatransfert.DataFlavor yTimers yFilechooser,Colorchooser yJava2D API yFenêtre texte xJTextField, JtextArea : idem AWT xJPasswordField : masquée xJEditorPane, JTextPane : editeur de texte complet (plusieurs polices simultanées..)

144 SWING : la hiérarchie classique d'une IG zLa fenêtre principale (top-level) : JFrame, ou JDialog ou JApplet zContient un root pane : en général, inutilisé par le programmeur, qui contient yglass pane : transparent et invisible sauf si sa méthode paint est définie. Il peut intercepter alors tous les événements du root pane ylayered pane : ensemble de couches, comprenant le Content Pane, utilisé par exemple pour les pop-up, le drag and drop, etc.. permettant et positionner les composants et dafficher par ordre de profondeur. Par defaut, contient la barre de menu et le ContentPane, sans superposition xbarre de menu : position de la barre de menu qui sera créée par JMenuBar et mise en place par setJMenuBar xContent Pane : utilisé par la plupart des applications et applets obtenu par GetContentPane() contient les composants, sauf la barre de menu facilite le placement des composants : il contient le gestionnaire de positionnement

145 SWING : Modèle objet zLe sous système graphique est objet ychaque composant s'affiche ychaque composant provoque l'affichage des composants qu'il contient yExemple : Ex30.java xLa fenêtre top level JFrame s'affiche xLe contentpane affiche un fond opaque xLe JPanel s'affiche (par dessus le précédent) : le fond (paintComponent()) les bordures(paintBorder()) xIl demande à son contenu de s'afficher(paintChildren()) Le JButton "Mon bouton" s'affiche par paintComponent() –le fond –le texte Le Jlabel "Du texte" s'affiche par paintComponent() –le texte zPour provoquer l'affichage, utiliser yrepaint() : affiche tout le composant yrepaint(int,int,int,int) : affiche le rectangle JFrame getContentPane () JButton Mon Bouton JPanel Jlabel Du Texte

146 SWING : les contrôles de base import javax.swing.*; import java.awt.*; class Testswing extends JFrame {super("les controlesf de base"); public Testswing(){ JPanel pane = new JPanel(); pane.add(new JButton("Mon bouton")); pane.add(new JLabel("Du texte")); pane.add(new JRadioButton("Bouton Radio")); pane.add(new JCheckBox("Case a cocher")); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte)); pane.add(new JSlider(JSlider.HORIZONTAL,0,5,3)); pane.add(new JTextField(5)); getContentPane().add(pane); pack(); setVisible(true); } public class Ex32 { public static void main(String[] args) { new Testswing();} }

147 SWING : les objets de base zLes boutons yClassique : JButton yJCheckBox pour les case à cocher yJRadioBouton pour un ensemble de bouton yJMenutItem pour un bouton dans un menu yJCheckBoxMenuItem yJRadioButtonMenuItem yJToggleButton Super Classe de CheckBox et Radio zJComboBox : composant permettant de faire un choix parmi plusieurs propositions zJList : liste à choix multiple en colonne zJSlider : saisie et visualisation graphique dun nombre entre 2 valeurs zJTextField: permet décrire du texte dans une zone monoligne zJTextArea: permet décrire du texte dans une zone multiligne zJLabel: permet dafficher du texte ou une image zJTree : affiche une arborecense zJFileChooser, JColorChooser zJProgressBar

148 Comment positionner les composants zPas de positionnement statique et fixé à lavance zDisposition et dimensionnement des objets dans une IG yEffectué à l'initialisation et au redimensionnement ydépend de l'ordre de création yde la politique de placement du containeur xflowlayout : ligne/ligne xborderlayout : position du composant défini par les points cardinaux (4+1) xgridlayout : grille (un par case) remplie de gauche à droite, de haut en bas xcardlayout : composants visibles séquentiellement (comme les onglets) xgridbaglayout : grille dont les composants peuvent occuper plusieurs cases ymethode setlayout(new borderlayout) : positionnement de la politique ypack() oblige les composants à prendre leur taille "préférée" ycomposant visible ou non : setVisible() zDisposition et dimensionnement absolu : possible, mais à éviter

149 Positionnement dans une IG

150 Swing : Borderlayout import javax.swing.*; import java.awt.*; class TestBorder extends JFrame { public TestBorder(){ super("Test du Border"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pane = new JPanel(new BorderLayout()); pane.add(new JButton("Mon bouton"),BorderLayout.NORTH); pane.add(new JLabel("Dutexte",JLabel.CENTER),BorderLayout.SOUTH); pane.add(new JRadioButton("Bouton Radio"),BorderLayout.EAST); pane.add(new JCheckBox("Case a cocher"),BorderLayout.WEST); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte),BorderLayout.CENTER); getContentPane().add(pane); pack(); setVisible(true); } public class Ex33 { public static void main(String[] args) { new TestBorder(); }

151 Swing : Gridlayout import javax.swing.*; import java.awt.*; class TestGrid extends JFrame { public TestGrid(){ super("Test du grid"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pane = new JPanel(new GridLayout(3,2)); pane.add(new JButton("Mon bouton")); pane.add(new JLabel("Du texte",JLabel.CENTER)); pane.add(new JRadioButton("Bouton Radio")); pane.add(new JCheckBox("Case a cocher")); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte)); pane.add(new JSlider(JSlider.HORIZONTAL,0,5,3)); pane.add(new JTextField(5)); getContentPane().add(pane); pack(); setVisible(true); } public class Ex34 { public static void main(String[] args) { new TestGrid(); }

152 Swing : Boxlayout import javax.swing.*; import java.awt.*; class TestBox extends JFrame { public TestBox(){ super("Test de BoxLayout "); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pane = new JPanel(); pane.setLayout(new BoxLayout(pane,BoxLayout.Y_AXIS)); pane.add(new JButton("Mon bouton")); pane.add(new JLabel("Du texte",JLabel.CENTER)); pane.add(new JRadioButton("Bouton Radio")); pane.add(new JCheckBox("Case a cocher")); String [] texte = { "aa","bb","cc","dd"}; pane.add(new JComboBox(texte)); pane.add(new JSlider(JSlider.HORIZONTAL,0,5,3)); pane.add(new JTextField(5)); getContentPane().add(pane); pack(); setVisible(true); } public class Ex35 { public static void main(String[] args) { new TestBox(); } }

153 Structurer une interface : description hiérarchique

154 Structurer linterface import javax.swing.*; import java.awt.*; // L'ordre d'inclusion n'a pas d'importance, les ajouts sont répercutés immédiatement class Pandanspan extends Jframe { public Pandanspan () { super("Hierarchique"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton button1 = new JButton("bouton1"); JLabel label1 = new JLabel("texte1"); JLabel label2 = new JLabel("texte2"); JButton button2 = new JButton("bouton2"); JButton button3 = new JButton("bouton3"); JButton button4 = new JButton("bouton4"); JButton button5 = new JButton("bouton5"); JPanel pane1 = new JPanel(new BorderLayout()); //layout spécifié à la construction JPanel pane2 = new JPanel(new BorderLayout()); JPanel pane3 = new JPanel(new BorderLayout()); pane1.add(button1, BorderLayout.EAST); pane1.add(label1, BorderLayout.WEST); pane1.add(pane2, BorderLayout.CENTER); pane2.add(button2, BorderLayout.NORTH); pane2.add(button3, BorderLayout.SOUTH); pane2.add(pane3, BorderLayout.CENTER); pane3.add(button4, BorderLayout.EAST); pane3.add(button5, BorderLayout.WEST); pane3.add(label2, BorderLayout.CENTER); getContentPane().add(pane1, BorderLayout.CENTER); pack(); setVisible(true); } public class Ex36 { public static void main(String[] args) { new Pandanspan(); } }

155 Créer un nouveau composant pour dessiner zLa classe Graphics est une classe abstraite ypermettant de dessiner des formes simples et des chaines de caractères yDetre indépendant du support réel :carte graphique, imprimante, image en mémoire y contient des informations sur : xLes couleurs daffichage, de fond, le type dopération de dessin (xor) xLe composant abstrait dans lequel on dessine zPour dessiner dans une fenetre: yOn crée un nouveau composant daffichage dérivant de JPanel et on redéfinit les méthodes xPaintComponent(Graphics g) pour laffichage xPaintBorder pour les bordures public void paintComponent(Graphics g) { super.paintComponent(g); //Le fond g.drawRect(10, 20, 99, 199); g.setColor(Color.yellow); // Dessine un rectangle jaune g.fillRect(10+1, ,98,198); }

156 Dessiner une liste de forme zOn utilise la liste de forme (rectangle et cercle) yCes classes sont modifiées pour avoir une méthode dessiner sur un élément de type Graphics. Chaque classe sait quel dessin elle doit faire zOn crée un nouveau composant AfficheForme qui contient la liste à afficher yCette liste est passée à la construction de Afficheforme yAfficheForme dérive de JPanel et sa méthode PaintCOmponent explicite le dessin à faire ie dessiner chaque forme de la liste abstract class Forme { protected Color couleur; …. } class Cercle extends Forme{ …… public void dessine(Graphics g) { g.setColor(couleur); g.fillOval(cdg.getx(),cdg.gety(),rayon,rayon); }; } class Rectangle extends Forme { …. public void dessine(Graphics g) { g.setColor(couleur); g.fillRect(cdg.getx(),cdg.gety(),largeur, hauteur);} };

157 Dessiner une liste de forme class AfficheForme extends JPanel { // nouveau composant affichant une liste de forme Collection liste; public AfficheForme( Collection l) { liste=l; } public void paintComponent(Graphics g) { super.paintComponent(g); for ( Forme a : liste) a.dessine(g); } public class Ex37 { public static void main (String []arg) { /* Creation de la liste de formes */ Collection liste= new LinkedList (); liste.add(new Cercle(10,20,30,Color.yellow)); liste.add(new Cercle(100,100,30,Color.green)); liste.add(new Rectangle(150,10,50,80,Color.magenta)); /* Creation de la fenetre et affichage par le composant Afficheforme */ JFrame f = new JFrame("Paint"); f.getContentPane().add(new AfficheForme(liste)); f.setSize(250,200); f.setVisible(true); f.repaint(); }

158 Graphics : couleurs, pinceaux zTous les attributs classiques de dessin sont disponibles à travers les classes et methodes de Java z zGestion des couleurs, épaisseur, etc. : setPaint, setStroke Remplissage : classes Color, GradientPaint, TexturePaint, TexturePaint. GradientPaint zTransformations affines AffineTransform textAt = new AffineTransform(); textAt.translate(0,(float)textTl.getBounds().getHeight());

159 Image zAWT : getImage, drawImage myImage = Toolkit.getDefaultToolkit().getImage(filenameOrURL); g.drawImage(myImage, 0, 0, this); zSWING : une image est simplement affichée dans un JPanel, un JButton yinterface icons yClasse ImageIcon : implemente icons, lit du GIF ou JPEG, mais aussi des BufferedImage (!= Image) yla fonction paintIcon(Component,Graphics,int,int) personnalise l'affichage d'une image si besoin (assez rare) yExemple : classe Ex2 au début zJava2D : On utilise la classe BufferedImage qui définit de nombreux outils de rendu, de filtrage, etc… yImageIO.read(File), ImageIO.write(BufferedImage, "Format",File) yg.drawImage(….) : affiche limage, applique des filtres

160 Afficher une image dans un composant (1) class AfficheImage extends JLabel { private ImageIcon icon=null; public AfficheImage(String im) { updateImage(im); } public void updateImage(String im) { icon=new ImageIcon(im); setIcon(icon);} // Creation et affichage de limage } class AppliAffiche extends JFrame { private AfficheImage affiche =null; public AppliAffiche(String im) { getContentPane().add(affiche=new AfficheImage(im)); pack(); setVisible(true); } public void suite(String im) { affiche.updateImage(im); pack(); } } public class Ex40 { public static void main (String []arg) { Scanner clavier = new Scanner(System.in); if (arg==null) {System.out.println("Usage : java Ex40 im1 im2...."); } else { AppliAffiche p = new AppliAffiche(arg[0]); System.out.println("Photo suivante"); clavier.nextLine(); for (int i=1; i

161 Afficher une image dans un composant (2) class AfficheImage extends JPanel{ private BufferedImage img = null; public AfficheImage(BufferedImage i) { img=i;} public void updateImage(BufferedImage i) { img=i; repaint();} public void paintComponent(Graphics g) { g.drawImage(img, 0, 0, null); } public Dimension getPreferredSize() { return (img==null) ? new Dimension(100,100): new Dimension(img.getWidth(null), img.getHeight(null)); } class AppliAffiche extends JFrame { private AfficheImage affiche =null; public AppliAffiche(BufferedImage im) { getContentPane().add(affiche=new AfficheImage(im)); pack(); setVisible(true); } public void suite(BufferedImage im) { affiche.updateImage(im); pack(); } } public class Ex40b { public static void main(String [] arg) {Scanner clavier = new Scanner(System.in); BufferedImage img = null; if (arg==null) {System.out.println("Usage : java Ex40 im1 im2...."); } else { try { img = ImageIO.read(new File(arg[0])); } catch (IOException e) {} AppliAffiche p = new AppliAffiche(img); System.out.println("Photo suivante"); clavier.nextLine(); for (int i=1; i

162 Menu 1.Création dune barre de menu JMenuBar barreMenu=new JMenuBar(); 2.Création dun menu, type Fichier, Edition, …. JMenu menu=new JMenu("Formes"); 3.Création des éléments du menu JMenuItem item1=new JMenuItem("Sauver"); 4.Ajout des éléments au menu menu.add(item1); 5.Ajout du menu à la barre barreMenu.add(menu); 6.Remarque : un JMenuItem génère un événement de type ActionEvent lorsquil est sélectionné 1.Voir la gestion des événements en JAVA

163 Menu import javax.swing.*; class TestMenu extends JFrame { private JMenuBar menuBar; public TestMenu() { super("exemple"); creationMenu(); getContentPane().add(new JPanel()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400,300); setVisible(true); } private void creationMenu() { menuBar = new JMenuBar(); JMenu menu = new JMenu("Fichier"); JMenu menu2 = new JMenu("Formes"); JMenu submenu = new JMenu("Formes simples"); menu.add(new JMenuItem("Nouveau")); menu.add(new JMenuItem("Ouvrir")); menu.add(new JMenuItem("Sauver")); menu2.add(submenu); submenu.add(new JMenuItem("Rectangle")); submenu.add(new JMenuItem("Cercle")); menuBar.add(menu); menuBar.add(menu2); setJMenuBar(menuBar); } public class Ex41 { public static void main (String []arg) { new TestMenu(); } }

164 JAVA Gestion des évènements en SWING

165 Gestion des évenements zQue se passe t il ? yquand on appuie sur un bouton, yquand on ferme une fenetre, yquand on bouge la souris … zUn événement contenant le lieu, la nature et lobjet « actionné » est créé par le système graphique. Cet événement est différent selon quil sagit dun clic sur un bouton, le déplacement de la souris, etc… zCet événement est mis dans lEDT (Emploi du temps ou mieux, Event Dispatcher Thread). zLe « dispatcher » envoie cet événement aux objets qui se sont déclarés intéressés par cet événement zQui est intéressé ? yDes objets de type écouteur (aux portes) yCest le bouton qui provoque les événements qui autorise les écoutes. yLes objets écouteurs (un ou plusieurs) définissent l(es) action(s) qui doivent avoir lieu yCette action est définie par un Listener, fonction qui précise lentete des fonctions gérant laction. Ce sont des callback dans dautres systemes.

166 Ecouter un bouton : premier exemple zIl faut créer linterface graphique : yune fenetre de base yUn bouton zIl faut créer la classe qui ecoute (ici Monecouteur) : elle implémente linterface actionlistener qui permet de gérer les clics sur un bouton, les sélections de menu yOn définit dans cette classe la méthode actionPerformed(…) qui explicite ce qui doit être fait quand on clique sur un bouton : ici on affiche sur la fenetre console le texte « Action sur le bouton » zOn crée un objet de cette classe : objetecoutant yEn pratique, le nom de la variable est souvent inutile : on crée des objets anonymes, sans nom On enregistre cet objet aupres du bouton par la méthode addActionListener, car cest quand meme le bouton qui autorise ou non lecoute

167 Ecouter un bouton et réagir import javax.swing.*; import java.awt.*; import java.awt.event.*; class Ecouteur1 extends JFrame { private JButton button; public Ecouteur1 () { super("exemple ecouteur 1"); button = new JButton("Appuyer pour afficher un texte"); Monecouteur objetecoutant = new Monecouteur(); button.addActionListener(objetecoutant); add(button, BorderLayout.CENTER); pack(); setVisible(true); } /* Classe interne à la classe ecouteur1 souvent utilisée pour les listener On peut aussi définir une classe externe. */ class Monecouteur implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Action surle bouton"); } } public class Ex45 { public static void main(String[] args) { new Ecouteur1();} }

168 Fermer la fenetre zIl faut créer linterface graphique : cest le meme code zIl faut créer une classe (ici Monecouteurfenetre) qui implémente linterface windowlistener qui permet de gérer les fenetres yIl faut définir 7 méthodes, meme si elles sont vides xvoid windowOpened(WindowEvent e) : ouverture de la fenetre xvoid windowClosed(WindowEvent e) : apres la fermeture de la fenetre xvoid windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre xvoid windowIconified(WindowEvent e) : iconifier la fenetre xvoid windowDeiconified(WindowEvent e) : deiconifier de la fenetre xvoid windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence windowGainedFocus de WindowFocusListener xvoid windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de préférence windowLostFocus de WindowFocusListener zOn crée un objet anonyme, sans nom car cest inutile On enregistre cet objet aupres de la fenetre par la méthode addWindowListener

169 Fermer la fenetre import javax.swing.*; import java.awt.*; import java.awt.event.*; class Ecouteur1 { private JButton button; JFrame frame; public Ecouteur1 () { frame=new JFrame("exemple ecouteur 1"); button = new JButton("Appuyer pour afficher un texte"); Monecouteur objetecoutant = new Monecouteur(); button.addActionListener(objetecoutant); frame.addWindowListener(new Monecouteurfenetre()); frame.add(button, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } class Monecouteur implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Action surle bouton"); } } class Monecouteurfenetre implements WindowListener { public void windowClosing(WindowEvent event) { System.exit(0); } public void windowClosed(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} } public class Ex45b { public static void main(String[] args) { new Ecouteur1();}}

170 Les adapteurs : Fermer la fenetre zGérer les événements par adaptateur yune interface listener toutes les méthodes doivent être écrites, même vides yexemple : windowsListener : 7 méthodes à redéfinir windowActivated, windowClosed, windowClosing, W indowDeactivated, windowDeiconified, windowIconified, windowOpened yUn adaptateur : une classe contient déjà une version vide on ne surcharge que les fonctionnalités dont on a besoin yAttention : la classe ecouteur HERITE de la classe Adapter au lieu de IMPLEMENTE une interface xComponentAdapter xContainerAdapter xFocusAdapter xKeyAdapter xMouseAdapter xMouseMotionAdapter xWindowAdapter

171 Ecouter 2 boutons (1) zUne application qui affiche un compteur mis à jour par 2 boutons zIl faut créer linterface graphique : yune fenêtre de base yun bouton « plus », un bouton « moins » yUn label qui affiche le compteur yUne variable entière contenant le compteur zPour gérer les boutons, plusieurs solutions yVersion objet avec 2 écouteurs : une classe écouteur spécifique pour chaque bouton. Il y a donc 2 classes, une pour le moins, une pour le plus. Aucun test nest à faire dans l'écouteur, puisquil sait quel bouton est utilisé yVersion 1 écouteur : une seule classe écouteur, qui teste si le composant doù provient lévénement est le bouton plus ou le bouton moins yVersion 1 ecouteur this : la classe ecouteur est la classe qui définit lapplication elle-même

172 Ecouter 2 boutons (1) import javax.swing.*; import java.awt.*; import java.awt.event.*; // Deux boutons : un qui décrémente, un qui incrémente class Ecouteur2 extends JFrame { private int count = 0; JLabel label; JButton buttonPlus, buttonMoins; private void creationinterface() { buttonPlus = new JButton("plus"); buttonMoins = new JButton("moins"); label = new JLabel("0", JLabel.CENTER); JPanel buttons = new JPanel(new GridLayout(0, 1)); buttons.add(buttonPlus); buttons.add(buttonMoins); JPanel pane = new JPanel(new BorderLayout()); pane.add(buttons, BorderLayout.WEST); pane.add(label, BorderLayout.CENTER); getContentPane().add(pane, BorderLayout.CENTER); pack(); setVisible(true); } public Ecouteur2() { super("exemple"); creationinterface(); buttonPlus.addActionListener(new MyActionListener1()); buttonMoins.addActionListener(new MyActionListener2()); addWindowListener(new MyWindowListener ()); }

173 Ecouter 2 boutons : 2 ecouteurs private class MyActionListener1 implements ActionListener { public void actionPerformed(ActionEvent event) { count++; label.setText(Integer.toString(count)); } private class MyActionListener2 implements ActionListener { public void actionPerformed(ActionEvent event) { count--; label.setText(Integer.toString(count)); } } // Remarque ; les classes internes ont accès aux champs de linterface private class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } public class Ex46 { public static void main(String[] args) { new Ecouteur2(); } }

174 Ecouter 2 boutons : 1 seul ecouteur private class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent event) { if(event.getSource() == buttonPlus) count++; else count--; label.setText(Integer.toString(count)); } private class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } public class Ex47 { public static void main(String[] args) { new Ecouteur2(); } }

175 Ecouter 2 boutons : 1 ecouteur=this import javax.swing.*; import java.awt.*; import java.awt.event.*; class Ecouteur2 extends WindowAdapter implements ActionListener {JFrame frame; private int count = 0; JLabel label; JButton buttonPlus, buttonMoins; private void creationinterface() { frame=new JFrame("Exemple"); buttonPlus = new JButton("plus"); buttonMoins = new JButton("moins"); label = new JLabel("0", JLabel.CENTER); JPanel buttons = new JPanel(new GridLayout(0, 1)); buttons.add(buttonPlus); buttons.add(buttonMoins); JPanel pane = new JPanel(new BorderLayout()); pane.add(buttons, BorderLayout.WEST); pane.add(label, BorderLayout.CENTER); frame.getContentPane().add(pane, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } public Ecouteur2() { creationinterface(); buttonPlus.addActionListener(this); buttonMoins.addActionListener(this); frame.addWindowListener(this); } public void actionPerformed(ActionEvent event) { if(event.getSource() == buttonPlus) count++; if(event.getSource() == buttonMoins) count--; label.setText(Integer.toString(count)); } public void windowClosing(WindowEvent event) { System.exit(0); } } public class Ex48 {public static void main(String[] args) { new Ecouteur2(); } }

176 Résumé zla gestion des événements est faite par délégation par un listener ou un adapter yl'événement n'est pas géré par le composant source de lévénement mais par un objet qui s'est déclaré intéressé (écouteur) par ce type d'événement au moyen de add Listener() ou set Listener() auprès de l'objet source ycet objet écouteur doit implanter la ou les méthodes précisées par le type de listener. Ces méthodes décrivent ce qui doit être fait avec l'événement. Un listener est une interface au sens Java du terme. Il faut définir toutes les méthodes de linterface, même si elles sont vides. yUn adapter est une classe contenant des versions vides des méthodes. On redéfinit uniquement celles qui sont nécessaires. Une classe ecouteur doit alors héritée de ladapter. ys'il existe plusieurs objets écouteurs, tous reçoivent une copie de l'événement dans un ordre non défini. ySi aucun listener n'est défini, l'événement est ignoré yun écouteur peut écouter plusieurs sources différentes yUn objet peut écouter plusieurs boutons yUn objet peut écouter les événements issu de ses propres composants zEn pratique yDéfinir et cééer linterface graphique et ses boutons. yDéfinir les écouteurs et les actions : ecrire les classes (Monecouteur) et méthodes (ActionPerformed) yCréer les ecouteurs des différents composants graphiques (new Monecouteur()) yEnregistrer les ecouteurs aupres des boutons à écouter (addActionListener(…))

177 Résumé zLes évènements sont typés, organisé en classes Mouse MouseEvent, clicbouton ActionEvent zMéthodes utiles String getActionCommand() : retourne la chaîne associée à l'évènement int getModifiers() : entier contenant les touches enfoncées par l'utilisateur (SHIFT,CTR) yObject getSource() : composant émettant l'événement yint getID() : retourne le type de lévénement ylong getWhen() : retourne le temps écoulé depuis lapparition de lévènement

178 Quel écouteur définir pour quelle action ? zInterface ActionListener yUtilisée par les clics bouton, choix de menu, et les CR dans un zone de texte (JTextField, JTextArea) yMéthodes à définir xvoid actionPerformed(ActionEvent e) : que faire lors de l'apparition dun des évènements zInterface MouseListener ou classe MouseAdapter yUtilisée pour les actions souris entrant et sortant dans la fenetre, les clics dans la fenetre yMéthodes à définir xvoid mouseClicked(MouseEvent e) : clic dans la fenetre xvoid mouseEntered(MouseEvent e) : souris entrant dans la fenetre xvoid mouseExited(MouseEvent e) : souris sortant de la fenetre xvoid mousePressed(MouseEvent e) : touche souris appuyée dans la fenetre xvoid mouseRealised(MouseEvent e) : touche souris relachée dans la fenetre yPrincipales méthodes de la classe MouseEvent xboolean isAltDown(), boolean isControlDown(), boolean isMetaDown(), boolean isShiftDown() xint getModifiers(), int getX(), int getY() yMéthodes utiles xboolean isLeftMouseButton(MouseEvent e) : vrai si e concerne le bouton gauche de la souris xboolean isMiddleMouseButton(MouseEvent e) : vrai si e concerne le bouton milieu de la souris xboolean isRightMouseButton(MouseEvent e) : vrai si e concerne le bouton droit de la souris zInterface MouseMotionListener ou classe MouseMotionAdapter yUtilisée pour les déplacement souris dans la fenetre yMéthodes à définir xvoid mouseDragged(MouseEvent e) : clic dans la fenetre xvoid mouseMovedMouseEvent e) : déplacement souris dans la fenetre

179 Exemple pour la souris import javax.swing.*;import java.awt.event.*;import java.awt.*; class Appli extends JFrame { JLabel zone1; public Appli() { zone1 = new JLabel("Test de mouse",Jlabel.CENTER); zone1.addMouseMotionListener(new Ecouteur()); getContentPane().add(zone1); setSize(200,200); setVisible(true); } private class Ecouteur implements MouseMotionListener { private void affiche(MouseEvent e) { System.out.println("x= "+e.getX()+", y="+e.getY()); ` } public void mouseMoved(MouseEvent e) { System.out.print("Mouvement"); affiche(e); } public void mouseDragged(MouseEvent e) { System.out.print("Glisser"); affiche(e); } } public class Ex49 { public static void main(String[] args) { new Appli(); } }

180 Quel écouteur définir pour quelle action (2) ? zInterface KeyListener ou classe KeyAdapter yUtilisée pour les actions clavier sur un composant Le Composant doit pouvoir obtenir le focus avec setFocusable(true) yMéthodes à définir xvoid keyTyped(KeyEvent e) : touche unicode (ascii) tapée xvoid keyPressed(KeyEvent e) : touche quelconque appuyée dans le composant xvoid keyRealised(KeyEvent e) : touche quelconque relachée dans le composant yPrincipales méthodes de la classe KeyEvent xboolean isActionKey() xint getKeyChar(), int getKeyCode() zInterface ChangeListener yUtilisée les Sliders, les ColorChooser, les Spinners yMéthodes à définir xvoid stateChanged(ChangeEvent e) : changement dans le composant zInterface ItemListener yUtilisée les checkBoxes, les ComboBoxes yMéthodes à définir xvoid itemStateChanged(ItemEvent e) : changement dans le composant yPrincipales méthodes de la classe ItemEvent xItemSelectable getItemSelectable() : similaire à getSource() xObject getItem(), int getStateChange()

181 Quel écouteur définir pour quelle action (3) ? zInterface WindowListener ou classe WindowAdapter yUtilisée pour les actions sur les fenetres : ouverture, fermeture, iconification, quitter yMéthodes à définir xvoid windowOpened(WindowEvent e) : ouverture de la fenetre xvoid windowClosed(WindowEvent e) : apres la fermeture de la fenetre xvoid windowClosing(WindowEvent e) : au moment de la fermeture de la fenetre xvoid windowIconified(WindowEvent e) : iconifier la fenetre xvoid windowDeiconified(WindowEvent e) : deiconifier de la fenetre xvoid windowActivated(WindowEvent e) : focus dans la fenetre; Utiliser de préférence windowGainedFocus de WindowFocusListener xvoid windowDeactivated(WindowEvent e) : perte du focus de la fenetre. Utiliser de préférence windowLostFocus de WindowFocusListener zLa principale action à redéfinir est celle de la fermeture dune application. Pour cela, il faudrait ySoit vos applications graphiques implémentent linterface WindowListener avec ses 7 methodes xredéfinir systématiquement la fonction windowClosed xEcrire un corps de fonction vide pour les autres ySoit vos applications graphiques héritent de WindowAdapter avec ses 7 methodes xredéfinir systématiquement la fonction windowClosed xMais votre application ne peut plus hérité dune autre classe zSolution : la méthode définit la sortie propre sans redéfinir le listener ou ladapter ysetDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

182 Un chat local (1) zTaper du texte dans une fenêtre, Recevoir dans une autre, avec ascenseur

183 Chat local (2) import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Ex51 { private JTextArea texte, copie; public Ex51() { // Fenetre principale qui envoie JFrame frame = new JFrame("Chat"); // Gestion de la sortie de fenetre frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Création du panel de la fenetre principale JPanel panelprincipal = new JPanel(new BorderLayout()); texte = new JTextArea(); // Partie texte de la Fenetre demission JScrollPane paneltexte = new JScrollPane (texte); // Bouton de la Fenetre demission JButton button = new JButton("Envoyer"); panelprincipal.add(paneltexte, BorderLayout.CENTER); panelprincipal.add(button, BorderLayout.SOUTH); // Gestion de l'appui sur le bouton "Envoyer" button.addActionListener(new MyActionListener()); frame.getContentPane().add(panelprincipal);

184 Chat local (3) // Creation de la deuxième fenetre pour la reception JFrame fenetrecopie = new JFrame("Fenetre de reception"); // Création d'une zone de texte pour le message recu avec edition impossible copie = new JTextArea(); copie.setEditable(false); // Creation du panel de la fenetre de reception JScrollPane panelcopie = new JScrollPane (copie); fenetrecopie.getContentPane().add(panelcopie); frame.setSize(200, 200); frame.setLocation(0, 0); frame.setVisible(true); fenetrecopie.setSize(200, 200); fenetrecopie.setLocation(400, 0); fenetrecopie. setVisible(true); } private class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent event) { copie.append(texte.getText() + "\n"); // Lecture dans la fenetre d'emission (texte) texte.setText(""); // et ecriture dans la fenetre de reception } public static void main(String[] args) { new Ex51();} }

185 Swing : Applets (1) zApplet dérive de JApplet : possède un root pane yPossède un unique contentPane ybarre de menu disponible yConséquences xajout des composants dans le ContentPane, pas dans l'applet xidem pour le gestionnaire de placement (layout) zSous système graphique ychaque composant se redessine à partir de la hiérarchie objet de l'IG x inutile et dangereux de redéfinir paint ou update x paintComponent d'un composant assure l'affichage personnalisé zlIG de l'applet est créée dans la fonction init() par ajout de composants zLes actions sont définies par les ecouteurs/adapteurs zPlug-in java pour utiliser swing dans les applets yBalise APPLET maintenant

186 Swing : Applets (2) import javax.swing.*; import java.awt.*; public class HelloSwingApplet extends JApplet { public void init() { JLabel label = new Jlabel ("Hello Swing applet!"); label.setHorizontalAlignment(JLabel.CENTER); label.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); getContentPane().add(label, BorderLayout.CENTER); } Swing Applet Your browser does not support Java, so nothing is displayed.

187 Swing : les threads zEn SWING, pas de difficultés si l'application ne modifie pas ses propres composants yExemple: création de l'IG dans init() pour l'applet, modification dans les gestionnaires d'événements zDans le cas contraire, les composants swing ne doivent être accessibles que par un thread à la fois. zRègle générale yConstruire l'application dans le thread principal, Construire l'applet dans init yles threads secondaires passent par les gestionnaires d'événements (sans action directe sur l'IG) pour leur modification yles méthodes repaint() et revalidate() postent des messages et ne modifient pas directement l'IG : utilisables. zPour les cas spéciaux, exécution de code utilisateur par le thread event- dispatching invokeLater : soumet la requête (met en evenement dans la file dev) et n'attend pas invokeAndWait : soumet la requête et attend

188 Swing : JTable zJTable : javax.swing.table yTableau dont les cellules sont des Component yUn Modèle (AbstractTableModel), une vue (Jtable) yEn général JTable dans une JScrollPane. Sinon, pas d'entêtes de colonnes zModèle par défaut yDonnées dans un vector ou un tableau yCellules éditables zUne table peut provoquer des événements pour faire réagir d'autres objets yson modèle doit les créer par appels de méthode fireTablexxx provoque les événements xfireTableCellUpdated, fireTableChanged, fireTableDataChanged, fireTableRowsDeleted, fireTableRowsInserted, fireTableRowsUpdated, fireTableStructureChanged yl'objet récepteur (écouteur) doit implémenter l'interface public class SimpleTableDemo... implements TableModelListener {... public SimpleTableDemo() {... model = table.getModel(); model.addTableModelListener(this);... } public void tableChanged(TableModelEvent e) {... int row = e.getFirstRow(); int column = e.getColumn(); String columnName = model.getColumnName(column); Object data = model.getValueAt(row, column);... }

189 Swing : Jtable (2) import javax.swing.*; import java.awt.*; import javax.swing.table.*; public class jtab2 { public static void main(String [] a){ Object [][] donnees = { {"8h-9h", new Integer(100),"Mathématiques"}, {"9h-10h",new Integer(10),"Physique"},{"10h-11h", new Integer(190),"Chimie"} }; String [] enTete = { "Heures", "Salle", "Matières"}; DefaultTableModel dtm = new DefaultTableModel(donnees, enTete); JTable jt = new JTable(dtm); JScrollPane jsp = new JScrollPane(jt); JFrame appl = new JFrame("Exemple de table : emploi du temps"); JPanel p1 = new JPanel(new BorderLayout()); appl.getContentPane().add(p1); p1.add(jsp); appl.pack(); appl.show(); } zJTable yles colonnes sont des objets yindexées à partir de 0 yméthodes pour changer la largeur d'une colonnes x(jt.getColumnModel().getColumn(1)).setPreferredWidth(10);

190 Swing : Jtable (3) zJTable : construire son propre modèle Class MonModel extends AbstractTableModel() { String [] entete = {......}; Object [][] donnees = {.....}; public String getColumnName(int col) { return entete[col].toString(); } public int getRowCount() { return donnees.length; } public int getColumnCount() { return entete.length; } public Class getColumnClass(int c){return getValueAt(0, c).getClass();} public Object getValueAt(int row, int col) { return donnees[row][col]; } public boolean isCellEditable(int row, int col) { return true; // ICI on met celles qui peuvent changer} public void setValueAt(Object value, int row, int col) { donnees[row][col] = value; fireTableCellUpdated(row, col); }

191 Labels et Onglets zJLabel : Image possible Icon image = new ImageIcon("image.jpg"); JLabel labelImage = new JLabel(image); zJTabbedPane : Onglet yaddTab : ajoute un onglet import java.awt.*; import java.util.*; import java.awt.event.*; import javax.swing.*; public class TabTest extends JPanel { private JTabbedPane jtp; private JLabel labelImage; private JPanel panneau1 = new JPanel(); private JPanel panneau2 = new JPanel(); private JPanel panneau3 = new JPanel(); public TabTest() { setLayout(new BorderLayout()); jtp = new JTabbedPane(); Icon image = new ImageIcon("dauphin09.jpg"); labelImage = new JLabel("dauphins nageants", image, SwingConstants.CENTER); panneau1.add(labelImage); Icon image2 = new ImageIcon("chien.gif"); panneau2.add(new JLabel(image2)); panneau3.add(new JLabel("JLabel avec du texte seulement")); jtp.addTab("Image & Texte", panneau1); jtp.addTab("image seule", panneau2); jtp.addTab("texte seul", panneau3); add(jtp, BorderLayout.CENTER); } public static void main(String args[]) { JFrame jf = new JFrame("Tabbed Pane Test"); TabTest tt = new TabTest(); jf.getContentPane().add(tt, BorderLayout.CENTER); jf.setSize(600,300); jf.setVisible(true); }

192 Labels et Onglets

193 JTree import java.awt.*; import javax.swing.*; import javax.swing.tree.*; public class jtree { private static Object [] nodeNames = { "one", "two", "three", "four", "five", "six", "seven", new Integer(8), new Integer(9), new Float(10) }; private static boolean [] leaf = { false, true, true, false, true, true, false, true, true, true }; public static void main(String args[]) { JFrame jf = new JFrame("Tree Test"); DefaultMutableTreeNode [] nodes = new DefaultMutableTreeNode[10]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new DefaultMutableTreeNode(nodeNames[i], !leaf[i]); } nodes[0].add(nodes[1]); nodes[0].add(nodes[2]); nodes[0].add(nodes[3]); nodes[0].add(nodes[6]); nodes[0].add(nodes[9]); nodes[3].add(nodes[4]); nodes[3].add(nodes[5]); nodes[6].add(nodes[7]); nodes[6].add(nodes[8]); JTree jt = new JTree(nodes[0]); jf.getContentPane().add(jt, BorderLayout.CENTER); jf.pack(); jf.setVisible(true); }

194 Exemple : JTree


Télécharger ppt "Programmation Objet et JAVA Phelma 2012 1. Organisation du cours z4 cours de 2h yJava, la notion dObjet et de Classes yLhéritage et le polymorphisme yLes."

Présentations similaires


Annonces Google