Это еще один из тех вопросов SCJP.Код ниже печатает Alpha:fooBeta:fooBeta:barBeta:bar
, и я не понимаю, почему первый вызов foo выбрал foo Альфы вместо беты.Если параметр Alpha.foo изменяется на String вместо String ..., то вывод будет Beta:fooBeta:fooBeta:barBeta:bar
, что имеет смысл.
Насколько я понимаю, когда вы говорите Alpha a = new Beta();
, компилятор проверяет наличие Alpha.foo, но JVM фактически запустит Beta.foo.Во-первых, у Beta есть метод foo, чья сигнатура соответствует вызову.С другой стороны, я думал, что методы varargs запускаются только тогда, когда нет другого доступного метода, соответствующего вызову.Так что это две причины, я думаю, что Alpha.foo не должен запускаться.Какая часть этого понимания неверна?
Спасибо!
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");
} }
Редактировать: Мне кажется, я знаю, где я теперь неправильно понял вещи.Я думал, что в ситуации SuperClass sc = new SubClass();
любой метод, вызываемый на sc, будет найден в SubClass во время выполнения, хотя он будет найден в SuperClass во время компиляции.Оказывается, как я теперь понимаю, я понимаю, что любой метод, вызываемый в sc, будет искать в SuperClass в и во время компиляции и во время выполнения, UNLESS SubClass предоставил «лучшую» версиюметод.Тогда даже во время компиляции компилятор будет знать, что вызываемый метод является версией подкласса.