Égalité entre objets                        

Égalité entre objets

           

Si on veut tester si deux objets (ou tableaux) sont identiques, il ne suffit pas de comparer les références des objets ; celles-ci peuvent être différentes et les objets (ou tableaux) néanmoins identiques. En fait, la notion d'égalité entre objets n'est pas universelle et c'est au programmeur de décrire dans une classe qu'il définit, et s'il le souhaite, ce qu'il considère comme étant l'égalité entre deux objets.
La classe Object définie une méthode d'en-tête :
    public boolean equals(Object obj)
qui ne fait que comparer l'adresse de l'objet concerné à l'adresse de l'objet reçu en paramètre.
Pour permettre de savoir si deux objets d'une classe A ont des contenus considérés comme identiques, on peut redéfinir dans la classe A la méthode equals de la classe Object comme le montre le programme ci-dessous (on peut aussi définir sa propre méthode d'égalité mais c'est moins bien que d'utiliser la méthode equals prévue à cet effet dans la classe Object et qu'il suffit de redéfinir).
On remarquera l'utilisation du mot instanceof ; dans la classe Identite, on décide que pour qu'un objet soit égal à un objet de la classe Identite, il faut en premier lieu qu'il soit de type Identite.

class Identite {    
    private String nom;  
    private String prenom;
    
    Identite(String nom, String prenom) {
	this.nom = nom;
	this.prenom = prenom;
    }

    String getNom() {
	return nom;
    }

    String getPrenom() {
	return prenom;
    }

  public boolean equals(Object obj) {
      return (obj instanceof Identite) && 
	  ((Identite)obj).getNom().equals(nom) && 
	  ((Identite)obj).getPrenom().equals(prenom);
    }
}

class Info { 
    private int val;
    private Identite identite ; 

    Info(int val, String nom, String prenom) {
	this.val = val;
	identite = new Identite(nom, prenom);
    }

    int getVal() {
	return val;
    }

    Identite getIdentite() {
	return identite;
    }
  
  public boolean equals(Object obj) {
      return  (obj instanceof Info) &&
	  (((Info)obj).getVal() == this.val) &&
	  ((Info)obj).getIdentite().equals(identite);
  }
}

class EssaiInfo  {
  public static void main(String arg[]) {
      Info info1 = new Info(15, "Charon", "Irene");
      Info info2 = new Info(15, "Charon", "Irene");
      Info info3 = new Info(15, "Charon", "Lou");
      Info info4 = new Info(12, "Charon", "Irene");

      System.out.println("avec ==, info1 et info2 sont egaux : " + (info1 == info2));
      System.out.println("avec equals, info1 et info2 sont egaux : " + info1.equals(info2));
      System.out.println("avec equals, info1 et info3 sont egaux : " + info1.equals(info3));
      System.out.println("avec equals, info1 et info4 sont egaux : " + info1.equals(info4));
  }
}
On obtient :
avec ==, info1 et info2 sont egaux : false
avec equals, info1 et info2 sont egaux : true
avec equals, info1 et info3 sont egaux : false
avec equals, info1 et info4 sont egaux : false

Pour accéder à cet ensemble de classes.


((Info)obj).getIdentite().equals(identite); : on utilise ici la méthode equals de la classe Identite ; pour tester correctement l'égalité entre objets, il faut souvent ainsi tester récursivement l'égalité des objets qui sont attributs de ceux-ci.
System.out.println("avec ==, info1 et info2 sont egaux : " + (info1 == info2)); : on obtiendra ici false car, bien que info1 et info2 aient des contenus identiques, ce sont deux objets distincts et ils ont donc des adresses différentes, et == compare ici l'adresse des objets.
System.out.println("avec equals, info1 et info2 sont egaux : " + info1.equals(info2)); : on obtiendra ici true car on a redéfinit la méthode equals de la classe Object afin de comparer les contenus des objets. Si on n'avait pas redéfini cette méthode, on obtiendrait false ; en effet, equals utiliserait alors la méthode equals définie dans la classe Object, méthode qui compare les adresses des objets concernés ; ces adresses sont ici différentes car info1 et info2 sont deux objets distincts.

© Charon Irène, Télécom ParisTech - Paris 2010