LIMITES DE L’HERITAGE SIMPLE Figure Componant {abstract} {abstract} translater(dx:integer, dy:integer) zoomer(facteurZoom:real) {abstract} Label Rectangle Cercle rayon:real RAPPELS ET COMPLEMENTS SUR LES INTERFACES EN JAVA zoomer(facteurZoom:real) Button hauteur:real Largeur:real zoomer(facteurZoom:real) static public void translaterZoomer(Figure[] tabF, int dx, int dy, double facteurZoom) { for (Figure f : tabF) { f.translater(dx, dy); f.zoomer(facteurZoom); } } static public void translaterZoomer(Label[] tabL, int dx, int dy, double facteurZoom) { for (Label l : tabL) { l.setLocation(l.getX()+dx,l.getY()+dy); Font policeIni = l.getFont(); l.setFont(policeIni.deriveFont( (int)(policeIni.getSize()*facteurZoom)); } } Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 1 Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 2 FACTORISATION PAR LES INTERFACES interface Visualisable { void translater(int dx, int dy); void zoomer(double facteurZoom); } class Figure implements Visualisable { //... } class LabelVisu implements Visualisable extends Label { public void translater(int dx, int dy) { setLocation(getX()+dx,getY()+dy); } public void zoomer(double facteurZoom) { Font policeIni = getFont(); setFont( policeIni.deriveFont( (int)(policeIni.getSize()*facteurZoom)); }} Visualisable Componant translater(dx:integer, dy:integer) zoomer(facteurZoom:real) {abstract} FACTORISATION PAR LES INTERFACES (2) //... static public void translaterZoomer( Visualisable[] tabV, int dx, int dy, double facteurZoom) { for (Visualisable v : tabV) { v.translater(dx, dy); v.zoomer(facteurZoom); } } //... Figure[] tF = new Figure[2]; translaterZoomer(tF); // OK car Figure implémente Visualisable LabelVisu[] tL = new LabelVisu[3]; translaterZoomer(tL); // OK car LabelVisu implémente Visualisable Figure {abstract} Label translater(dx:integer, dy:integer) LabelVisu Cercle rayon:real translater(dx:integer, dy:integer) zoomer(facteurZoom:real) zoomer(facteurZoom:real) Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 3 Visualizable[] tV = new Visualisable[3]; tV[0] = new Rectangle(...); tV[1] = new Cercle (...); tV[2] = new LabelVisu (...); translaterZoomer(tV); Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 4 NATURE ET INTERET DES INTERFACES DEFINITIONS D’INTERFACES • exemples : • définition abstraite d'un service, indépendamment de la façon dont il est implémenté ("type abstrait de données") • concrètement, ensemble de méthodes publiques abstraites (et de constantes de classe) • facilite la programmation “générique” • permet un héritage multiple restreint Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 5 interface Redimensionnable { void grossir(int facteur); void reduire(int facteur); } interface Coloriable { void colorier(Couleur c); } interface Pile { void empiler(Object o); Object sommet(); void depiler(); boolean estVide(); } Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 6 UTILISATION DES INTERFACES REFERENCES DE TYPE INTERFACE • utilisation : toute classe peut implémenter une (ou plusieurs) interface(s) : • Chaque interface définit un type de référence • une référence à interface peut désigner toute instance de toute classe qui implémente l'interface en question : class Cercle implements Coloriable,Redimensionnable { //... } • une classe qui implémente une interface doit redéfinir toutes les méthodes de l'interface (ou bien être abstraite) : class Cercle implements Coloriable,Redimensionnable { //... public void grossir(int facteur) { rayon *= facteur; } public void reduire(int facteur){...} public void colorier(Couleur c){...} } abstract class Figure implements Coloriable { // classe abstraite ==> pas indispensable // de redéfinir colorier() Redimensionnable redim; Coloriable col; Cercle cercle = new Cercle(); redim = cercle; col = cercle; // cercle, col et redim forment // 3 vues différentes du même objet... // ...et les méthodes applicables dépendent // de la vue utilisée : col.colorier(Color.red); // OK col.grossir(2); // ERREUR redim.grossir(2); // OK cercle.colorier(Color.red); // OK // ... } Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 7 Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 8 INTERFACES ET HERITAGE INTERFACES “MARQUEURS" • une interface peut dériver d'une (ou plusieurs) autres interfaces • une interface peut ne contenir aucune méthode ni constante, et servir juste de "marqueur" pour indiquer une propriété des classes qui l'implémentent • exemples : – interface Cloneable pour identifier les classes aux instances desquelles on peut appliquer la méthode de duplication clone() interface X {...} interface Y {...} interface Z extends X,Y{...} • si une classe Mere implémente une interface, alors toutes ses classes filles héritent de cette propriété : class class //... Z z = X x = Mere implements Z{...} Fille extends Mere {...} – interface Serializable pour identifier les classes dont on peut sauvegarder des instances sur fichier (cf java.io) new Fille(); // OK new Fille(); // OK // car Fille implémente (par héritage) // l'interface Z (et donc aussi X) Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 9 Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 10 INTERET DES INTERFACES (comparées aux classes abstraites) Version SANS interface • Permettent de contourner les limitations liées à l’impossibilité en Java de faire de l’héritage « multiple » (≠ ≠ C++) : cf. exemple précédent • Offre plus de flexibilité, notamment pour des développements ultérieurs Version AVEC interface Collection AbstractCollection {abstract} AbstractList {abstract} Set List ListeSpeciale AbstractSequentialList {abstract} ArrayList LinkedList Rappels et compléments de Java sur les « interfaces » LES INTERFACES FACILITENT LA REUTILISATION Fabien Moutarde 11 En privilégiant les interfaces comme types pour les attributs, ainsi que types de retour et paramètres d’opérations, on rend la classe plus facilement réutilisable Ici : cette nouvelle version de Population pourra servir avec des individus de toute classe implémentant EtreVivant, par exemple Animal Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 12 PRINCIPE DE REUTILISATION PAR DELEGATION Personne réutilise les propriétés d’Animal liées aux opérations renvoyerAge(), vieillir(), et afficherNom(), sans hériter celles qui sont inappropriées INTERFACES ET DELEGATION • L’interface EtreVivant permet de manipuler de façon homogène des instances de Personne et d’Animal , malgré la délégation utilisée par Personne Note : la délégation est un exemple de « design pattern » Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 13 Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 14 REMPLACEMENT HERITAGE PAR DELEGATION + INTERFACES entrees.addAll(autreDico.entrees); Classe fille « fragile » vis-à-vis simples modifs implémentation ds classe mère Interface + délégation réduction dépendances, mais en réutilisant quand même… Rappels et compléments de Java sur les « interfaces » Fabien Moutarde 15