2016-10-02 2 views
1

Почему следующий код генерирует вывод «в супер», когда тип объекта является подклассом (OtherClass2), а аргумент тестовой функции имеет тип Person2? Не следует ли тестировать вызов метода (новый Person2()); вызвать тестовую функцию подкласса?Перегрузка подкласса Java-класса не вызывается из суперкласса

public class HelloWorld 
{ 
    public static void main(String[] args) 
    { 
    OtherClass2 s = new OtherClass2(); 


    s.goToThing(); 
    } 
} 

public class Person 
{ 

} 

public class Person2 extends Person 
{ 

} 

public class OtherClass 
{ 
    public void hello() 
    { 
    test(new Person2()); 
    } 

    public void test(Person p) 
    { 
    System.out.println("in super"); 
    } 
} 

public class OtherClass2 extends OtherClass 
{ 
    public void test(Person2 g) 
    { 
    System.out.println("In sub"); 
    } 

    public void goToThing() 
    { 
    hello(); 
    } 
} 
+0

Перегрузка происходит во время компиляции; компилятор решает вызвать 'test (Person)', а затем, когда ваша программа запускается, проверяет, есть ли в подклассе 'test (Person)', которого нет. – immibis

ответ

1
public void test(Person2 g) 

из OtherClass2 не переопределяет

public void test(Person p) 

из OtherClass. Он перегружает его. Тем не менее, он перегружает его только для переменных, тип времени компиляции которых равен OtherClass2 (так как перегрузка определяется во время компиляции).

Поэтому

test(new Person2()); 

вызывает метод public void test(Person p) из суперкласса, так как OtherClass не имеет метода с подписью public void test(Person2 g) (который мог бы быть переопределен test методом OtherClass2).

Если бы вы добавили аннотацию @Override выше public void test(Person2 g), компилятор сказал бы вам, что этот метод не переопределяет какой-либо метод суперкласса.

1

Поскольку ваш тестовый метод в OtherClass2 не отменяет проверку в OtherClass (он перегружает). ли вы иметь

public class OtherClass2 extends OtherClass 
{ 
    public void test(Person g) 
    { 
    System.out.println("In sub"); 
    } 

    public void goToThing() 
    { 
    hello(); 
    } 
} 

он будет работать, как ожидалось.

См. Дополнительную информацию и differences between overriding and overloading.

0

Потому что hello(); способ находится в OtherClass. Вы звоните goToThing(), который находится в OtherClass2, после чего OtherClass2 вызывает метод hello(), который в OtherClass, hello() метод вызывает test() метод от OtherClass. Попробуйте следующее:

public class OtherClass2 extends OtherClass 
{ 
    public void hello() 
    { 
     test(new Person2()); 
    } 
    public void test(Person2 g) 
    { 
    System.out.println("In sub"); 
    } 

    public void goToThing() 
    { 
    hello(); 
    } 
} 
Смежные вопросы