Доступ к методу Java в процессе полиморфизма

У меня есть следующий код Java.

class A {

        public void method1() {
            System.out.println("A 1");
            method2();
        }

        public void method2() {
            System.out.println("A 2");
        }

    }

    class B extends A {
        @Override
        public void method2() {
            System.out.println("B 2");
        }
    }

    public class Tester {
        public static void main(String[] args) {
            A a = new B();
            a.method1();
        }
    }

Это печатает

    A 1
    B 2
  • Что именно происходит во время выполнения, когда вызывается a.method1()?
  • Как вызывается производный метод от родителя?
  • Это смотрит на объект и строку имени метода и вызывает метод во время выполнения?
  • Он вызывает this.method2() по умолчанию?

5 ответов

Решение

Так как метод method1(...) никогда не был переопределен, B наследует A method1() и это называется, как если бы оно было определено в B.

поскольку method1() звонки method2() переопределенный метод method2() определенный в B вызывается, когда экземпляр был создан с помощью конструктора B.

Если вы создадите другой экземпляр с конструктором A, вы не получите переопределенный method2(...) определено в B, но получить оригинал method2(...) определено в А.

Что именно происходит во время выполнения, когда вызывается a.method1()?

вызывается метод method1 () класса A.

Как вызывается производный метод от родителя?

Так как вы использовали метод, method2 в классе B это будет метод, который будет вызываться во время выполнения.

Это смотрит на объект и строку имени метода и вызывает метод во время выполнения?

Не путайся здесь. Когда ты пишешь

 A a = new B();

Методы из класса B вызываются, если они ovveridden, иначе из A вызывается.

Он вызывает this.method2() по умолчанию?

Опять же, это не дефолт. Если вы ovveride, он вызывается из B. Если вы не ovveride, он вызывается из A

Когда объект типа B инициализируется, он является экземпляром класса B, даже если он неявно приводится к объекту типа A.

Следовательно, когда вы звоните a.method1() поскольку method1() не определен в классе B, он вызывает метод, определенный в базовом классе. Тогда в свою очередь, когда method2() называется, он определен в классе B, и, поскольку объект имеет тип B, вызывается метод в классе B.

Потому что ваш объект на самом деле имеет тип B что наследуется от A, внутри вашего Bкласс вы переопределяете method2, поэтому он вызывает B.method2()

  A a = new B();

Звонить method2 от A, используйте:

  A a = new A();

Вы создали класс Object of Child и объект типа Reference. Ссылка имеет тип Parent (Down-casting)

Когда вы вызываете любой метод по ссылке, будет вызван метод со ссылкой на тип. Но если метод недоступен в ссылочном типе, он будет вызван из Parent (Inheritance).

В вашем примере компилятор проверяет метод method1 в объекте A и находит его там. Во-вторых, когда метод2 вызывается, он вызывается из текущего объекта (объект B вместо ссылки A).

Обратите внимание, поскольку метод2 переопределяется, когда вы вызываете его из ссылки A, он будет вызывать метод из объекта A (родительский), а если вы вызываете его из ссылки B, он будет вызывать из объекта B(дочерний).

Ключевым моментом, который следует помнить здесь, является разница в Reference и Object Они оба разные сущности.

* То же самое произойдет, если вы вызовете конкретный метод из абстрактного класса, который вызывает абстрактный метод того же класса. Будет вызван метод реализации дочернего класса.

Другие вопросы по тегам