COURS DE PROGRAMMATION ORIENTEE OBJET : Classes internes
LES CLASSES INTERNES Une classe interne est une classe qui est définie à l’intérieur d’une autre classe. Intérêts d’utiliser des classes internes Elles peuvent être cachées aux autres classes du même package. Leurs méthodes peuvent accéder aux données de la classe ou de l’interface où elles sont définies, même les données privées. Les classes internes anonymes sont utiles pour implémenter certaines interfaces ou étendre des classes abstraites de manière efficace.
Types de classes internes LES CLASSES INTERNES Types de classes internes Classes internes public class A { private (ou public) class B { } } Classes internes statiques public class A { public static class B { Classes internes locales public class A { public void m(){ class B { } } } Classes internes anonymes public class A { public void m(){ new SuperType() { };
Classe interne LES CLASSES INTERNES Une classe interne possède une référence sur sa classe englobante. Une classe englobante a accès à tous les membres de sa classe interne (même privés). Une classe interne a accès à tous les membres d'une classe englobante.
LES CLASSES INTERNES Classe interne Référence à la classe externe dans la classe interne : ClasseExterne.this Appel du constructeur de l’objet interne : Dans la classe externe : new ClasseInterne(…) Hors de la classe externe, si la classe interne est publique ClasseExterne objetExterne = new ClasseExterne(…); ClasseExterne.ClasseInterne objetInterne= objetExterne .new ClasseInterne(…);
LES CLASSES INTERNES Classe interne - Exemple1 public class Suite { private final char[] tab; public class SousSuite { private final int debut; private final int longueur; public SousSuite (int debut, int lng) { this.debut=debut; this.longueur=longueur; } public char charAt ( int index ) { if ( index<0 || index>=lng ) throw new IllegalArgumentException(...); return tab[debut+index];
LES CLASSES INTERNES Classe interne – Exemple1 Instanciation de la classe SousSuite à l’extérieur de la classe Suite : Suite s = new Suite("toto"); SousSuite sub = s.new SousSuite(1,3); System.out.println( sub.charAt(0) );
LES CLASSES INTERNES Classe interne – Exemple1 public class Suite { Instanciation de la classe SousSuite à l’intérieur de la classe Suite public class Suite { private final char[] tab; public class SousSuite { public SousSuite(int debut,int longueur) { } … public SousSuite extraireSousSuite(int debut) { return new SousSuite(debut,tab.longueur-debut); // return Suite.this.new SousSuite(...)
LES CLASSES INTERNES Classe interne – Exemple2 Modifier la classe CompteBancaire de manière à rajouter un champ derOperation qui mémorise la dernière opération réalisée (retrait ou dépôt) ainsi que le montant de l’opération. On souhaite pouvoir afficher, pour un compte donné, le numéro du compte suivi de la dernière opération réalisée sur le compte et le montant de celle-ci.
LES CLASSES INTERNES Classe interne – Exemple2 public class CompteBanquaire{ private String nom ; private String adresse ; private int numero ; private int solde; private Operation derOperation; public class Operation{ private String op; private long montant; Operation(String op, int montant){ this.op=op; this.montant= montant; } public String toString(){ return numero"+":"+op+" "+montant; //return CompteBancaire.this.numero"+":"+op+" "+montant;
LES CLASSES INTERNES Classe interne – Exemple2 public void crediter(int montant){ solde += montant; derOperation=new Operation("depot",montant); } public void debiter(int montant){ solde -= montant; derOperation=new Operation("retrait",montant); }//fin de la classe CompteBancaire
LES CLASSES INTERNES Classe interne et compilateur Les classes internes sont traduites en fichiers de classes réguliers par le compilateur. Le compilateur ajoute un champs vers la classe englobante et change l'appel au constructeur.
LES CLASSES INTERNES Classe interne locale Dans certains cas, on ne doit utiliser un objet de la classe interne que dans une seule méthode de la classe englobante. On peut alors définir une classe interne locale à une méthode.
Classe interne locale LES CLASSES INTERNES La portée de la classe interne est réduite au bloc dans laquelle elle est déclarée. Une classe interne locale est analogue à une variable locale, elle n'est pas membre de la classe. La classe est complètement cachée au reste du code de la classe englobante et aux autres objets.
Classe interne locale LES CLASSES INTERNES Utilisation1 : créer des instances qui peuvent être passées en paramètres. Utilisation2 : créer des objets d'une extension d'une classe qui n'a de sens que localement (en particulier dans les interfaces graphiques).
Classe interne locale LES CLASSES INTERNES Exemple : Dans l’étude des Collections Java, nous fournirons plusieurs implémentations de la méthode public Iterator iterator() permettant de parcourir chaque élément d’une collection d’éléments. Cette méthode retourne un objet de type Iterator qui est une interface.
Classe interne locale LES CLASSES INTERNES public interface Iterator{ //renvoie true si l’objet de l’itération possède encore //au moins un élément public boolean hasNext(); public Object next() throws NoSuchElementException; public void remove() throws UnsupportedOperationException; }
LES CLASSES INTERNES Classe interne locale public Iterator iterator(){ class Iterateur implements Iterator{ public boolean hasNext(){…} public Object next() throws NoSuchElementException{…} public void remove() throws UnsupportedOperationException{…} } return new Iterateur();
On définit une classe interne anonyme. LES CLASSES INTERNES Classe interne anonyme Lors de l’utilisation d’une classe interne locale, si on ne souhaite créer qu’un seul objet de cette classe, il n’est pas nécessaire de donner un nom à la classe. On définit une classe interne anonyme.
LES CLASSES INTERNES Classe interne anonyme – Syntaxe public class A{ … public void methodeDeA(…, final type parametre){ SuperType s = new SuperType(paramètres de construction) { méthodes et données de la classe interne }; }
Classe interne anonyme – Syntaxe LES CLASSES INTERNES Classe interne anonyme – Syntaxe SuperType peut être une interface; la classe interne implémente alors cette interface. une classe; la classe interne étend alors cette classe. Une classe interne anonyme ne peut pas avoir de constructeurs propres.
Classe interne anonyme – Syntaxe LES CLASSES INTERNES Classe interne anonyme – Syntaxe Dans le cas d’une interface, il n’y aura pas de paramètres de construction. New TypeInterface () { méthodes et données } La classe interne anonyme peut appeler les paramètres définis dans la méthode englobante avec le modificateur final.
Classe interne anonyme Exemple avec l’interface Iterator : LES CLASSES INTERNES Classe interne anonyme Exemple avec l’interface Iterator : public Iterator iterator(){ return new Iterator(){ public boolean hasNext(){…} public Object next() throws NoSuchElementException{…} public void remove() throws UnsupportedOperationException{…} }; }
Classe interne statique LES CLASSES INTERNES Classe interne statique utile pour cacher des détails d’implémentation. elle ne va pas utiliser de référence à un objet de la classe englobante. elle accède uniquement aux champs statiques de la classe englobante.
Classe interne statique – Exemple LES CLASSES INTERNES Classe interne statique – Exemple On souhaite calculer les valeurs minimales et maximales d’un tableau en ne parcourant le tableau qu’une seule fois. On déclare une classe TableauOperation et on crée une méthode statique minMax avec comme paramètre un tableau de double. minMax doit retourner deux nombres. Pour cela on déclare une classe Pair qui stocke deux valeurs numériques.
Classe interne statique – Exemple LES CLASSES INTERNES Classe interne statique – Exemple public class TableauOperations{ public static Pair minMax (double[] values){ double max = Double.MAX_VALUE; double min = Double.MIN_VALUE; for (double v : values){ if (min > v) min = v; if (max < v) max = v; } return new Pair (min, max); L’objet de la classe interne Pair est construit dans une méthode statique. La classe Pair doit être statique.
Classe interne statique – Exemple LES CLASSES INTERNES Classe interne statique – Exemple public static Pair { private double premier; private double second; public Pair (double p, double s){ premier = p; second = s; } public double getPremier(){ return premier;} public double getSecond(){ return second;} }//fin de la classe TableauOperations La classe Pair ne possède pas de référence à l’objet externe qui l’a créé.
LES CLASSES INTERNES Classe interne statique – Exemple public class minMaxTest{ public static void main (String[] args){ double[] d= new double[20]; for (int i =0; i< d.length; i++) d[i] = 100* Math.random(); TableauOperations.Pair p = TableauOperations.minMax(d); System.out.println(" min = " + p.getPremier()); System.out.println(" max = " + p.getSecond()); }