Вызов функции переопределения базового класса из метода базового класса
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
public class B extends A {
@Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
@Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.f1("Hello");
}
}
Я ищу, чтобы этот код выводил:
B.f1(String)
A.f1(String)
A.f1(int, String)
Но я получаю:
B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)
Я понимаю, что в контексте B "this" в A.f1 (String) есть B instance.
У меня есть возможность сделать цепочку new B1(). F1 (String) → (A) f1 (String) → (A) f1 (int, String)?
Это теоретический вопрос, практически решение, очевидно, было бы в для реализации частной функции, которую вызывали бы как f1 (String), так и f1 (int, String).
Спасибо,
Максим.
Ответы
Ответ 1
К сожалению, no
Как я уверен, вы знаете, но я точно укажу на полноту - для управления вызовом метода есть только 2 ключевых слова:
- this -
this.method()
- ищет метод, начинающийся с вызывающего класса экземпляра (виртуальная таблица экземпляра "по умолчанию" ) подразумевается по умолчанию.
- super -
super.method()
- ищет метод, начинающийся с родительского класса класса, в котором определяется метод вызова (родительская виртуальная таблица вызова класса не строго верно, но проще думать об этом - спасибо @maaartinus)
Я могу представить, что другое ключевое слово (например, current?) делает то, что вы описываете:
- current -
current.method()
- ищет метод, начинающийся с класса, в котором определяется метод вызова
но Java не имеет такого ключевого слова (пока?).
Ответ 2
Я боюсь, это невозможно, но есть простой способ:
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
privateF1(1, str);
}
private void privateF1(int i, String str) {
System.out.println("A.f1(int, String)");
}
public void f1(int i, String str) {
privateF1(i, str);
}
}
Ответ 3
Переопределенные методы в Java динамически связаны. то есть тип фактического экземпляра объекта диктует, что будет вызываться. final
методы (которые нельзя переопределить) и методы private
(которые не могут быть унаследованы) статически связаны.
В С++ для контраста вам нужно явно сделать функции virtual
для получения того же поведения.
Ответ 4
package main;
public class A {
public void f1(String str) {
System.out.println("A.f1(String)");
if (this instanceof B)
new A().f1(1, str);
else
this.f1(1, str);
}
public void f1(int i, String str) {
System.out.println("A.f1(int, String)");
}
}
class B extends A {
@Override
public void f1(String str) {
System.out.println("B.f1(String)");
super.f1(str);
}
@Override
public void f1(int i, String str) {
System.out.println("B.f1(int, String)");
super.f1(i, str);
}
public static void main(String[] args) {
A a = new B();
a.f1("Hello");
}
}