Для этого вам нужно использовать метод method1 не виртуальный. Чтобы сделать это, вы делаете его окончательным:
public final void method1() {....
Или вы делаете это частным; в Java методы pivate всегда не виртуальны:
private void method1() {....
(Обратите внимание, что в C ++ частные методы могут быть виртуальными или не виртуальными; среди прочего, это делает реализацию Template Method Pattern более чистой в C ++.)
Вот что происходит: когда нестатический метод вызывается через ссылку на объект (что является единственным способом вызова метода нестатического объекта в Java), вызываемый метод зависит от фактического типа упомянутого объекта. (указывает), а не тип ссылки.
В методе объекта вызовы других методов (или членов) этого объекта неявно имеют префикс «this». Итак, ваш вызов method1 в method2 действительно:
public void method2() {
this.method1();
System.out.println("A2");
}
И this
является ссылкой на объект. В методе 2, который находится в классе A, ссылка имеет тип A, как если бы было объявлено this
:
A this;
Но эта ссылка указывает на объект типа B
; это может быть сделано, потому что B является производным от, наследует, подклассов, is-a, A
.
Как я упоминал выше, «когда нестатический метод вызывается через ссылку на объект, вызываемый метод зависит от фактического типа объекта, на который делается ссылка, а не от типа ссылки». Когда вы создаете экземпляр объекта типа B и вызываете method2 (), переданный вами this
(this
на самом деле является скрытым параметром любой нестатической функции) - это this
, который указывает на объект B. Когда B.method2 () вызвал super (), тот же this
был передан A.method2 ().
Итак, когда A.method2 () вызвал method1 (), то, что действительно произошло, мы назвали this.method1()
с тем же this
, что относится к B
, B
, который вы создали в main()
и вызвал method2 () on.
Поскольку method1 () является виртуальным, и поскольку мы вызываем method1 () для ссылки на объект типа B
, компилятор гарантирует, что B
переопределит Метод1 () - это тот, который называется.