sistema - Código Java relacionado con el método igual
sistema de ecuaciones lineales c# (4)
El método igual en Prueba toma una instancia de Prueba.
Todos los intentos anteriores se han realizado con una instancia de Object, que toma el método heredado de la clase Object:
public boolean equals(Object o){
return this == o;
}
Como no hay impresión allí, no imprimirá ningún valor.
Tu
++count;
incrementará el valor de la cuenta, por lo que el momento en que realmente llama a su
public boolean equals(Test testje){...
método, que imprime ese valor, el valor de count es 4.
Estoy practicando para un examen y encontré un problema de muestra que no entiendo.
Para el siguiente código, encuentre cuál es la salida:
public class Test {
private static int count = 0;
public boolean equals(Test testje) {
System.out.println("count = " + count);
return false;
}
public static void main(String [] args) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
++count; t1.equals(t2);
++count; t1.equals(t3);
++count; t3.equals(o1);
++count; t3.equals(t3);
++count; t3.equals(t2);
}
}
El resultado de este código es
count = 4
, pero no entiendo por qué.
¿Alguien puede ayudarme?
Hay dos cosas clave que debes saber.
-
Los métodos anulados deben tener las firmas exactas que tiene su superclase. (en su ejemplo, esta condición no cumple).
-
En Java para un objeto, tenemos dos tipos: tipo de compilación y tipo de tiempo de ejecución . En el siguiente ejemplo, el tipo de compilación de
myobj
esObject
pero su tipo de tiempo de ejecución esCar
.public class Car{ @Override public boolean equals(Object o){ System.out.println("something"); return false; } }
Object myobj = new Car();
También debe tener en cuenta que
myobj.equals(...)
da como resultado la impresión desomething
en la consola.
Lo primero que debe tener en cuenta es que
public boolean equals(Test testje)
no
anula los
equals
Object
, ya que el argumento es
Test
lugar de
Object
, por lo que las firmas no coinciden.
Por lo tanto, el método
main
llama a
equals(Test testje)
exactamente una vez, cuando se ejecuta
t3.equals(t3);
- dado que ese es el único caso en el que se ejecuta tanto el tipo estático de la instancia como el tipo del argumento son la clase
Test
.
t3.equals(t3);
es la cuarta instrucción
equals
(que viene después de 4 incrementos de la variable de
count
estático), por lo que se imprime 4.
Todas las otras declaraciones
equals
ejecutan los
equals
Object
y, por lo tanto, no imprimen nada.
Una explicación más detallada:
t1.equals()
llama a los
equals
Object
sin importar el tipo de argumento, ya que el tipo estático (tiempo de compilación) de
t1
es
Object
, y la clase
Test
no anula ese método.
La clase
Object
no tiene un método
equals
con un solo argumento de
Test
, por lo que no se puede llamar a
equals(Test testje)
, independientemente de la dinámica (tipo de tiempo de ejecución) de
t1
.
t3.equals()
puede ejecutar los
equals
Object
o los de
Test
, ya que el tipo de tiempo de compilación de
t3
es
Test
, y la clase
Test
tiene dos métodos
equals
(uno heredado de la clase
Object
y el otro definido en el
Test
clase).
El método elegido depende del tipo de tiempo de compilación del argumento: 1. Cuando el argumento es
Object
(como en
t3.equals(o1);
o
t3.equals(t2);
), se llama
equals
Object
y nada es impreso.
2. Cuando el argumento es
Test
, como en
t3.equals(t3);
, ambas versiones de
equals
coinciden con ese argumento, pero debido a las reglas de sobrecarga de métodos, se elige el método con el argumento más específico -
equals(Test testje)
- y se imprime la variable de
count
.
t3.equals(t3)
es la única línea que tiene los argumentos correctos que coinciden con la firma del método
public boolean equals (Test testje)
por lo que es la única línea en el programa que realmente llama a esa declaración de impresión.
Esta pregunta está diseñada para enseñarle algunas cosas.
- Toda clase amplía implícitamente Object
- Object.java contiene un método igual que toma el tipo Object
- pueden existir varios métodos con el mismo nombre siempre que tengan diferentes argumentos; esto se conoce como sobrecarga de métodos
- El método que sobrecarga la firma de quién coincide con los argumentos en tiempo de ejecución es el método que se invoca.
Esencialmente, el truco aquí es que Test implícitamente extiende Object como todas las clases de Java. Object contiene un método igual que toma el tipo Object. t1 y t2 se escriben de tal manera que en tiempo de ejecución los argumentos nunca coinciden con la firma de método de iguales que se define en Prueba. En cambio, siempre está llamando al método de igualdad en Object.java porque el tipo base es Object en cuyo caso los únicos métodos a los que tiene acceso son los definidos en Object.java o el tipo derivado es Object en cuyo caso
public boolean equals(Test testje)
No se puede ingresar porque en ese caso en tiempo de ejecución el argumento es de tipo Object, que es una Superclase de prueba, no una subclase. Entonces, en cambio, observa el método de igualdad en la superclase Object.java de Test.java, que también contiene un método de igualdad, que simplemente tiene una firma de método de
public boolean equals (Object o)
que en este caso coincide con nuestros argumentos en tiempo de ejecución, por lo que este método igual es el que se ejecuta.
Observe que en el caso de
t3.equals(t3)
tanto el tipo base como el tipo derivado de t3 son Test.
Test t3 = new Test ();
Esto significa que en tiempo de ejecución está llamando al método igual en Test.java y el argumento que está pasando es en realidad de tipo Test, por lo que las firmas del método coinciden y se ejecuta el código dentro de Test.java.
En este punto
count == 4
.
Un poco de conocimiento adicional para ti:
@Override
La anotación que puede haber visto en algunos lugares indica explícitamente al compilador que falle si no encuentra un método con la misma firma en algún lugar de una Superclase. Esto es útil para saber si definitivamente tiene la intención de anular un método y desea estar absolutamente seguro de que realmente está anulando el método y no ha cambiado accidentalmente el método en la superclase o subclase, pero no en ambos y ha introducido un error de tiempo de ejecución donde se llama la implementación incorrecta del método que causa un comportamiento no deseado.