Ответ
Сокрытие метода (method hiding) — это механизм в Java, при котором статический метод в подклассе определяет новую реализацию для статического метода с той же сигнатурой из родительского класса. Важно: это относится только к статическим методам. Для нестатических (экземплярных) методов аналогичная ситуация называется переопределением (overriding).
Ключевое отличие от переопределения: При сокрытии используется раннее (статическое) связывание. Вызываемый метод определяется на этапе компиляции по типу ссылки, а не по типу реального объекта (как при полиморфизме и переопределении).
class Parent {
static void print() { // Статический метод
System.out.println("Static method in Parent");
}
void instancePrint() { // Метод экземпляра
System.out.println("Instance method in Parent");
}
}
class Child extends Parent {
// СОКРЫТИЕ СТАТИЧЕСКОГО МЕТОДА (Method Hiding)
static void print() {
System.out.println("Static method in Child");
}
// ПЕРЕОПРЕДЕЛЕНИЕ МЕТОДА ЭКЗЕМПЛЯРА (Overriding)
@Override
void instancePrint() {
System.out.println("Instance method in Child");
}
}
public class Main {
public static void main(String[] args) {
Parent parentRef = new Child(); // Ссылка типа Parent на объект Child
// Сокрытие: Выбор метода зависит от ТИПА ССЫЛКИ (Parent)
parentRef.print(); // Вывод: "Static method in Parent"
Parent.print(); // Вывод: "Static method in Parent"
Child.print(); // Вывод: "Static method in Child"
// Переопределение: Выбор метода зависит от ТИПА ОБЪЕКТА (Child)
parentRef.instancePrint(); // Вывод: "Instance method in Child" (Полиморфизм!)
}
}
Правила и рекомендации:
- Сокрытие статических методов разрешено, но часто считается плохой практикой, так как нарушает интуитивное ожидание полиморфного поведения и ведет к путанице.
- Для вызова скрытого родительского метода из подкласса используйте
super.print();(в нестатическом контексте) илиParent.print();. - Аннотация
@Overrideне применима к скрываемым статическим методам. Компилятор выдаст ошибку, так как это не переопределение. - Лучшая практика: Избегайте сокрытия. Для статических методов используйте уникальные имена в иерархии или обращайтесь к ним явно через имя класса (
ClassName.staticMethod()).