sobre programacion primero libro estuviera ejemplos como codigos aprenda java overloading

java - programacion - scala ejemplos



Cuando overriding es igual a Java, ¿por qué no funciona usar un parámetro distinto de Object? (7)

Me encontré con un comportamiento interesante recientemente. Parece que si anulo a .equals () para tomar un parámetro que no sea Object, no se llama. ¿Alguien puede explicarme por qué sucede esto? Parece violar mi comprensión del polimorfismo en OOP, pero tal vez me falta algo.

Aquí hay un código mucho más simple que muestra lo que estoy viendo:

public class MyClass { private int x; public MyClass(int n) { x = n; } public boolean equals(Object o) { return false; } public boolean equals(MyClass mc) { return x == mc.x; } public static void main(String[] args) { List<MyClass> list = new ArrayList<MyClass>(); list.add(new MyClass(3)); System.out.println("Contains 3? " + list.contains(new MyClass(3))); } }

Cuando se ejecuta, imprime " Contains 3? false ". Parece que se llama a la función igual (Objeto), aunque hay otra que funcionaría. Por el contrario, si escribo igual, el código funciona como se espera:

public boolean equals(Object o) { if(!(o instanceof MyClass)) return false; MyClass mc = (MyClass)o; return x == mc.x; }

¿Por qué no está averiguando qué versión de la función llamar según el tipo de parámetro?


De acuerdo, déjame reformular.

(1) Porque el compilador elimina toda la información relativa a Genéricos (borrado, ver aquí ), y (2) porque no puede anular un método sin la misma firma exacta (es igual a (Objeto)), (3) durante el tiempo de ejecución todos los objetos dentro del List se tratan como objetos y no como instancias de MyClass. Por lo tanto, el método que se llama es igual (Objeto) ya que este es el que ha sido sobrescrito por su clase.


Está asumiendo que el método contains() en List conoce el tipo de objeto en tiempo de ejecución, que es incorrecto.

Debido a la eliminación, List<MyClass> convierte en una List normal en tiempo de ejecución, por lo que el método contains() ve su parámetro como un Object , invocando así Equals equals() del Objeto en lugar de la que definió para MyClass en su ejecución.


Estás mezclando "anulación" y "sobrecarga".

Anulación: adición de una definición de reemplazo de un método existente para propósitos de polimorfismo. El método debe tener la misma firma. La firma consta de los tipos de nombre y argumento. Los métodos reemplazados se seleccionan en tiempo de ejecución en función del tipo de tiempo de ejecución del objeto de destino.

Sobrecarga: agregar un método con el mismo nombre pero con una firma diferente. Los métodos sobrecargados se seleccionan en tiempo de compilación en función del tipo de tiempo de compilación del objeto de destino.


La implementación de ArrayList del método contains (Object) está obligada a usar el método Object.equals (Object) internamente, por lo que nunca sabrá sobre la sobrecarga del método equals (MyClass). Solo se encontrará un método de anulación (con la firma correspondiente).


Tenga en cuenta que el método que está llamando se define en el javadoc para ArrayList <E > como

boolean contains(Object o) Returns true if this list contains the specified element.

en lugar de

boolean contains(E o) Returns true if this list contains the specified element.

Implementación de ArrayList.java:

private transient Object elementData[]; public boolean contains(Object elem) { return indexOf(elem) >= 0; } public int indexOf(Object elem) { if (elem == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (elem.equals(elementData[i])) return i; } return -1; }

Utiliza el método equals definido en la superclase Object dado que el método equals no se reemplaza en la implementación de ArrayList <E >.

Al anular Object es igual a java, también debe anular el método Object hashCode.

De todos modos, es posible que desee probar el siguiente código:

class A{ public int content; A(){ this(0); } A(int value){ content = value; } public boolean equals(Object obj){ System.out.println("overriding equals method"); return this.content == ((A) obj).content; } public boolean equals(A a){ System.out.println("overloading equals method"); return this.content == a.content; } public static void main(String[] args){ A x = new A(1); A y = new A(2); Object z = new A(1); System.out.println(x.equals(y)); System.out.println(x.equals(x)); System.out.println(x.equals(z)); //override as z is declared as Object at compile time //so it will use methods in class Object instead of class A System.out.println(x.equals((Object) y)); System.out.println(x.equals((Object) x)); } } //rant: they didn''t teach me these in javaschool and I had to learn it the hard way.


equals (Object) está anulando un supermétodo; no puede anular un supermétodo sin utilizar la misma firma exacta (Bueno, hay algunas excepciones como retornos covariantes y excepciones).