Доступ к методу 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 Они оба разные сущности.
* То же самое произойдет, если вы вызовете конкретный метод из абстрактного класса, который вызывает абстрактный метод того же класса. Будет вызван метод реализации дочернего класса.