CLASSE RACINE Object ancêtre de toutes les classes RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION) définit donc des méthodes héritées par toutes les classes : public String tostring() par défaut "NomClasse@"+hashCode(), mais à redéfinir en une représentation String de l'objet public boolean equals(object obj) par défaut, retourne this==obj, mais prévue pour être redéfinie en comparaison de contenu (ex : classe String) public int hashcode() protected Object clone() public Class getclass()... Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 1 Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 2
INTERET DE REDEFINIR METHODES HERITEES DE Object public Fraction(int n, int d) { num = n; denom = d; public void afficher() { System.out.println(num+"/"+denom); Fraction f1 = new Fraction(2,3); System.out.println(f1); // Fraction@82b41!! Fraction f2 = new Fraction(2,3); System.out.println(f1.equals(f2)); // false!! intérêt de toujours redéfinir les méthodes tostring() et equals(object) (et aussi hashcode()) dans vos classes Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 3 EXEMPLE DE REDEFINITION de equals(object) public Fraction(int n, int d) { num = n; denom = d; public void afficher() { System.out.println(this); public String tostring() { StringBuffer buf = new StringBuffer("/"); buf.insert(0, String.valueOf(num) ); buf.append( String.valueOf(denom) ); return buf.tostring(); public boolean equals(object autre) { if (!(autre instanceof Fraction) ) return false; else { Fraction f = (Fraction)autre; return num==f.num && denom==f.denom; // (ou bien num*f.denom==denom*f.num, // selon sémantique voulue ) Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 4
REDEFINITION de hashcode() Méthode utilisée par HashMap, HashSet, etc Par défaut, renvoie l adresse mémoire. Specs Java : a.equals(b) => a.hashcode()==b.hashcode(); Redéfinir hashcode() si equals(object) redéfinie hashcode() doit être : égal pour 2 instances «equals» rapide à calculer à valeurs «uniformément distribuées» Recettes possibles : combinaison de hashcode élémentaires choisir attributs significatifs [typiquement parmi ceux comparés dans equals()] calcul type result = 37*result +hash(attr) EXEMPLE DE REDEFINITION de hashcode() // public int hashcode() { return denom + 37*(17+37*num); // // Autre possibilité : // return tostring().hashcode(); // // Ou encore, utiliser une des fonctions du type : // java.util.arrays.hashcode(int[] t) // java.util.arrays.hashcode(double[] t) // java.util.arrays.deephashcode(object[] t) utiliser hashcode() de String (appliqué à une chaîne construite avec les «attributs significatifs» Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 5 Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 6
REDEFINITION DE clone() Fraction f = new Fraction(2,3); Fraction dup = (Fraction)(f.clone()); // si hors du package de Fraction ou de // sous-classe de Fraction, erreur // de compilation : clone() protected // sinon, erreur à l exécution : // CloneNotSupportedException class Fraction implements Cloneable { return super.clone(); Ici, utilisation du «clonage par défaut» hérité de Object (et consistant à copier attributs un par un) est OK Noter au passage l ouverture de visibilité PLUS LARGE lors de la redéfinition Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 7 METHODE clone() duplique l'objet auquel elle est appliquée (copie des attributs) tout objet (et tableau) en hérite utilisable directement pour les tableaux "ordinaires" : int[] tab={1,2,3,4; int[] tab2=(int[])(tab.clone()); // noter la conversion en int[] attention si tableau multi-dim ou d'objets, car copie des références pour les objets que l on veut clonables : 1/ déclarer que la classe implémente l'interface Cloneable, 2/ redéfinir la méthode clone() comme public, et soit retournant super.clone(), soit adaptée à la classe Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 8
REDEFINITION DE clone(): cas d attributs de type référence class CopieFaible implements Cloneable{ private int[] tab; private Fraction f; return super.clone(); CopieFaible original = new CopieFaible( ); CopieFaible copie = (CopieFaible)(original.clone()); // ATTENTION : // - copie.tab pointe vers MEME // tableau que original.tab // - copie.f pointe vers MEME // INSTANCE de Fraction que // original.f REDEFINITION DE clone(): cas d attributs de type référence (2) class CopieForte implements Cloneable{ private int[] tab; private Fraction f; CopieForte dup = (CopieForte)(super.clone()); dup.tab = (int[])(tab.clone()); dup.f = (Fraction)(f.clone()); return dup; les clones d une instance de CopieForte seront réellement totalement indépendants de l original Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 9 Rappels sur spécialisation des méthodes héritées de classe racine Object Fabien Moutarde 10