Мне определили статический метод в базовом классе, я хочу переопределить этот метод в его дочернем классе, действительно ли это возможно?
Я попробовал это, но это не работало, как я ожидал. Когда я создал экземпляр класса B, и вызовите его callMe () метод, статическое нечто (), метод в классе A вызывается.
public abstract class A {
public static void foo() {
System.out.println("I am base class");
}
public void callMe() {
foo();
}
}
Public class B {
public static void foo() {
System.out.println("I am child class");
}
}
Вызов статических методов разрешается во время компиляции (без динамической отправки).
class main {
public static void main(String args[]) {
A a = new B();
B b = new B();
a.foo();
b.foo();
a.callMe();
b.callMe();
}
}
abstract class A {
public static void foo() {
System.out.println("I am superclass");
}
public void callMe() {
foo(); //no late binding here; always calls A.foo()
}
}
class B extends A {
public static void foo() {
System.out.println("I am subclass");
}
}
дает
I am superclass
I am subclass
I am superclass
I am superclass
Статические методы разрешаются во время компиляции. Поэтому, если вы хотите вызвать метод родительского класса, вы должны явно вызвать его с className или instance, как показано ниже.
A.foo();
или
A a = new A();
a.foo();
В Java поиск статических методов определяется во время компиляции и не может адаптироваться к подклассам, которые загружаются после компиляции.
Просто добавлю почему. Обычно, когда вы вызываете метод, объект, к которому принадлежит метод, используется для поиска подходящей реализации. Вы получаете возможность переопределить метод, если объект предоставляет свой собственный метод вместо того, чтобы использовать метод, предоставленный родителем.
В случае статических методов нет объекта, который мог бы подсказать, какую реализацию использовать. Это означает, что компилятор может использовать только объявленный тип, чтобы выбрать реализацию метода для вызова.