Esta es otra de esas preguntas SCJP. El siguiente código imprime Alpha:fooBeta:fooBeta:barBeta:bar
, y no entiendo por qué la primera llamada de foo eligió Alpha's foo en lugar de Beta's. Si el parámetro Alpha.foo se cambia a String en lugar de String ..., la salida es Beta:fooBeta:fooBeta:barBeta:bar
, lo que tiene sentido.¿Cómo se eligió un método sobre otro en este código?
Según tengo entendido, cuando dice Alpha a = new Beta();
, el compilador busca Alpha.foo, pero la JVM realmente ejecutará Beta.foo. Por un lado, Beta tiene un método foo cuya firma coincide con la llamada. Por otro lado, pensé que los métodos varargs solo se ejecutan cuando no hay otro método disponible que coincida con la llamada. Así que esas son dos razones por las que creo que Alpha.foo no debería ejecutarse. ¿Qué parte de esta comprensión es incorrecta?
Gracias!
class Alpha {
public void foo(String... args) { //if this were String args, then it makes sense
System.out.print("Alpha:foo");
}
public void bar(String a) {
System.out.print("Alpha:bar");
} }
public class Beta extends Alpha {
public void foo(String a) {
System.out.print("Beta:foo");
}
public void bar(String a) {
System.out.print("Beta:bar");
}
public static void main(String[] arg) {
Alpha a = new Beta();
Beta b = (Beta) a;
a.foo("test");//confusing line
b.foo("test");
a.bar("test");
b.bar("test");
} }
Editar: Creo que sé dónde he malinterpretado las cosas ahora. Pensé que en una situación SuperClass sc = new SubClass();
, cualquier método que se solicite en sc se buscará en SubClass en tiempo de ejecución, aunque se buscará en SuperClass en tiempo de compilación. Resulta que, como ahora creo entender, cualquier método que se solicite sc se buscará en SuperClass en tiempo de compilación y tiempo de ejecución, A MENOS QUE SubClass haya proporcionado una versión "mejor" del método. Luego, incluso en tiempo de compilación, el compilador sabrá que el método para invocar es la versión SubClass.