Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Выполнив восходящее преобразование от производного в базовый класс метод не переопределился

#java #наследование


Выполнив восходящее преобразование от производного в базовый класс метод не переопределился?
Почему не вызвался метод nasvai() базового класса?

class BasicClass {
    void nasvai() { System.out.println("Basic_Nasvai"); }
}

class SubBasic extends BasicClass {
    @Override
    void nasvai() { System.out.println("Nasvai"); }
}

class P231Exc20 {
    public static void main (String[] args) {
            SubBasic sb = new SubBasic();
            sb.nasvai();
            BasicClass bc = sb;
            bc.nasvai();
    }
}


Вывод:

Nasvai
Nasvai

    


Ответы

Ответ 1



А он и не должен был переопределяться. В Java (в отличии от С++ к примеру) все функции делаются виртуальными (virtual) и для поиска функции, которую необходимо вызвать, используется специальная таблица (VMT) которая (упрощённо) каждому объекту при создании ставит в соответствие его тип (по конструктору). И исходя из типа вызывает нужную функцию. При преобразовании типа сохраняется запись в VMT и соответственно происходит вызов функции исходя из типа созданного объекта а не связанной с ним переменной.

Ответ 2



Если коротко - "потому что полиморфизм". Так работает наследование в джаве. Более того, определив class BasicClass {    public BasicClass() { nasvai(); } void nasvai() { System.out.println("Basic_Nasvai"); } } и создав экземпляр дочернего класса, вы увидите, что будет вызван переопределённый метод. Поэтому не вызыввайте не-static не-final методы в конструкторе во избежание недоразумений.

Комментариев нет:

Отправить комментарий