Ir al contenido principal

EL MÉTODO EQUALS EN JAVA

SOBREESCRIBIR MÉTODOS TOSTRING Y EQUALS EN JAVA

Los métodos de la superclase universal Object estarán disponibles para todos los objetos. Dentro de los métodos de la clase Object hay varios importantes, entre los que podemos citar los métodos toString() que devuelve un tipo String y equals (Object obj) que devuelve un tipo boolean. 

 Veamos primero el método toString(). El propósito de este método es asociar a todo objeto un texto representativo. Llamar a toString() sobre un objeto Integer producirá un resultado que es más o menos obvio: nos devuelve el entero asociado, solo que en forma de String. ¿Pero qué ocurre cuando invocamos el método sobre un objeto definido por nosotros? Este sería el caso de una invocación como
System.out.println (“Obtenemos “ + profesor1.toString() );
En este caso, el resultado que obtenemos es del tipo:
“Obtenemos Profesor@1de9ac4”.
El método efectivamente nos ha devuelto un String, ¿pero qué sentido tiene lo que nos ha devuelto? El resultado obtenido consta del nombre de la clase seguido de una cadena “extraña” que representa la dirección de memoria en que se encuentra el objeto. Este resultado en general es poco útil por lo que el método toString() es un método que habitualmente se sobreescribe al crear una clase. De hecho, la mayoría de las clases de la biblioteca estándar de Java sobreescriben el método toString(). Por otro lado, es frecuente que cuando un programador incluye métodos como imprimir…, mostrar…, listar…, etc. de alguna manera dentro de ellos se realicen llamadas al método toString() para evitar la repetición de código. También es frecuente que toString() aparezca en tareas de depuración ya que nos permite interpretar de forma “humana” los objetos.
Supongamos que en nuestra clase Persona redefinimos toString() de la siguiente manera:
public String toString() { return nombre.concat(" "). concat(apellidos); }
En la clase profesor, que hereda de Persona, podríamos tener:
public String toString() { return super.toString().concat(" con Id de profesor: ").concat ( getIdProfesor() ); }
public void mostrarDatos() { System.out.println ("Los datos disponibles son: " + this.toString() ); }

En este ejemplo vemos, aparte del uso del método concat para concatenar Strings, una llamada a la superclase para recuperar el método toString de la superclase y cómo otro método (mostrarDatos) hace uso del método toString(). Usar toString es ventajoso porque no siempre nos interesa mostrar cadenas de texto por consolas en pantalla: tener los datos en un String nos permite p.ej. grabarlos en una base de datos, enviarlos en un correo electrónico, etc., además de poder mostrarlos por pantalla si queremos.
Conviene remarcar que cuando usamos los métodos println y print del objeto System.out, cuando se incluye un término que no es un String, se invoca automáticamente el método toString() del objeto sin necesidad de escribirlo de forma explícita. Así System.out.println (Profesor); es equivalente a System.out.println (Profesor.toString() );


SOBREESCRIBIR MÉTODOS DE LA CLASE OBJECT: MÉTODO EQUALS

Ya hemos utilizado el método equals en diferentes ocasiones y sabemos que es la forma en que debemos comparar objetos. Los objetos no se pueden comparar utilizando el operador ==. El método equals está implementado en el API de Java para la mayoría de las clases. Por ello, podemos usarlo directamente para comparar Strings por ejemplo. Ahora bien, ¿qué ocurre en una clase creada por nosotros? Si escribimos algo como if (profesor1.equals(profesor2)), al no estar sobreescrito el método equals para la clase Profesor, el resultado es impredecible o incorrecto. Por tanto, para comparar objetos de tipo Profesor hemos de sobreescribir el método en la clase. Vamos a ver cómo realizaríamos la sobreescritura de este método dentro de la estructura de herencia en la que venimos trabajando. 
Escribe y compila el código que mostramos a continuación y trata de comprenderlo.
// Código que añadimos a la clase Persona. Sobreescritura del método equals ejemplo aprenderaprogramar.com
    public boolean equals (Object obj) {
        if (obj instanceof Persona) {
        Persona tmpPersona = (Persona) obj;
            if (this.nombre.equals(tmpPersona.nombre) && this.apellidos.equals(tmpPersona.apellidos) &&
 this.edad == tmpPersona.edad) { return true; } else { return false; }
    } else { return false; }
//Cierre del método equals

// Código que añadimos a la clase Profesor. Sobreescritura del método equals ejemplo aprenderaprogramar.com
public boolean equals (Object obj) {
        if (obj instanceof Profesor) {
            Profesor tmpProfesor = (Profesor) obj;
            if (super.equals(tmpProfesor) && this.IdProfesor.equals(tmpProfesor.IdProfesor) ) {
                return true; } else { return false; }
        }  else { return false; }
    } // Cierre del método equals

//Clase test herencia método equals ejemplo aprenderaprogramar.com
import java.util.Calendar;
public class TestHerencia5{
    public static void main (String [ ] Args) {
        Profesor profesor1 = new Profesor ("Juan", "Hernández García", 33);
        profesor1.setIdProfesor("Prof 22-387-11");
        Profesor profesor2 = new Profesor ("Juan", "Hernández García", 33);
        profesor2.setIdProfesor("Prof 22-387-11");
        Profesor profesor3 = new Profesor ("Juan", "Hernández García", 33);
        profesor3.setIdProfesor("Prof 11-285-22");
        Persona persona1 = new Persona ("José", "Hernández López", 28);
        Persona persona2 = new Persona ("José", "Hernández López", 28);
        Persona persona3 = new Persona ("Ramiro", "Suárez Rodríguez", 19);
        System.out.println ("¿Son iguales la persona1 y la persona2? " + persona1.equals(persona2) );
        System.out.println ("¿Son el mismo objeto la persona1 y la persona2? " + (persona1 == persona2) ); 
        System.out.println ("¿Son iguales la persona1 y la persona3? " + persona1.equals(persona3) );  
        System.out.println ("¿Son iguales el profesor1 y el profesor2? " + profesor1.equals(profesor2) );
        System.out.println ("¿Son iguales el profesor1 y el profesor3? " + profesor1.equals(profesor3) );
    } //Cierre del main
//Cierre de la clase


Comprueba que obtienes estos resultados al ejecutar el main:
¿Son iguales la persona1 y la persona2? true
¿Son el mismo objeto la persona1 y la persona2? false
¿Son iguales la persona1 y la persona3? false
¿Son iguales el profesor1 y el profesor2? true
¿Son iguales el profesor1 y el profesor3? false


Analicemos ahora lo que hemos hecho.
En la clase Persona, mediante la sobreescritura del método equals, hemos definido que para nosotros dos personas van a ser iguales sí coinciden sus nombre, apellidos y edad. El criterio lo hemos fijado nosotros.
Otra opción hubiera sido establecer que dos personas son iguales sí coinciden nombre y apellidos. Fíjate que los Strings los comparamos usando el método equals del API de Java para los objetos de tipo String, mientras que la edad la comparamos con el operador == por ser un tipo primitivo.
Otra cuestión relevante es el tratamiento de tipos: el método equals requiere como parámetro un tipo Object y no un tipo Persona. Así hemos de escribirlo para que realmente sea una redefinición del método de la clase Object. Si usáramos otra signatura, no sería una redefinición o sobreescritura del método, sino un nuevo método.
En primer lugar, comprobamos si el objeto pasado como parámetro es un tipo Persona. Si no lo es, devolvemos como resultado del método false: los objetos no son iguales (no pueden serlo si ni siquiera coinciden sus tipos). En segundo lugar, una vez verificado que el objeto es portador de un tipo Persona, creamos una variable de tipo Persona a la que asignamos el objeto pasado como parámetro valiéndonos de casting (enmascaramiento). Esta variable la creamos para poder invocar campos y métodos de la clase Persona, ya que esto no podemos hacerlo sobre un objeto de tipo Object. Con esta variable, realizamos las comparaciones oportunas y devolvemos un resultado.
En la clase Profesor hemos sobreescrito también el método equals con un tratamiento de tipos y uso de casting similar. En este caso invocamos el método equals de la superclase Persona, con lo que decimos que para que dos profesores sean iguales han de coincidir nombre, apellidos y edad. Además, establecemos otro requisito para considerar a dos profesores iguales: que coincida su IdProfesor. Esto lo hacemos a nuestra conveniencia.

Finalmente, en el test realizamos pruebas de los métodos implementados, comprobando por ejemplo que una persona1 puede ser igual a otra persona2 (de acuerdo con la definición dada al método equals) pero ambas ser diferentes objetos.

Comentarios

Entradas populares de este blog

Ejemplos de Colecciones

En los siguientes vínculos encontrara un ejemplo de las diferentes colecciones en Java. Pulse "Más información". para ver todos los enlaces Enlace para ver el Ejemplo de HashSet Enlace para ver el Ejemplo de LinkedList Enlace para ver el  Ejemplo de TreeSet Enlace para ver el  Ejemplo de LinkedHasMap Enlace para ver el  Ejemplo de TreeMap Aquí seguiré agregando más ejemplo ...