Почему это называется "скрытие метода"?

Из документов: "Если подкласс определяет статический метод с той же сигнатурой, что и у статического метода в суперклассе, то метод в подклассе скрывает метод в суперклассе".

Я понимаю разницу между методом скрытия и переопределением. Однако странно сказать, что подкласс скрывает метод суперкласса, потому что если у вас есть следующее:

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

Статический метод суперкласса вызывается. Но по определению сокрытия метод в подклассе скрывает метод в суперклассе. Я не вижу, как подкласс "скрывает / скрывает" статический метод суперкласса, поскольку метод суперкласса является тем, который фактически вызывается.

4 ответа

Решение

Статический метод суперкласса вызывается.

Да. Но это потому, что вы явно назвали статический метод суперкласса, указав имя суперкласса в операторе вызова.

Если бы вы написали main как это вместо этого:

public static void main(String[] args) {
    ...
    testClassMethod();
}

тогда вы бы увидели, что Cat версия testClassMethod назывался. Здесь Cat.testClassMethod метод скрывает Animal.testClassMethod метод

Cat"s testClassMethod() шкуры Animal.testClassMethod(), так как если у вас не было статического testClassMethod() в Cat учебный класс, Cat.testClassMethod() будет ссылаться Animal.testClassMethod(),

Когда вы звоните Animal.testClassMethod(), он не может быть скрыт методом подкласса.

Вы можете добавить это в ваш пример

class Dog extends Animal {
    // nothing here
}

Теперь, если вы сделаете это:

new Cat().testClassMethod();
new Dog().testClassMethod();

каждый из вышеперечисленных даст разные результаты. Таким образом, вы можете сказать, что статический метод в Cat спрятал Animalстатический метод - хотя для статических методов не существует переопределения, одно из животных напечатано согласно Animalкод, а другой нет.

(PS Я определенно не советую вам вызывать статические методы таким образом.)

Я думаю, что это называется "скрытием", потому что вы больше не можете получить доступ к методу суперкласса, просто написав имя метода. Без public static void testClassMethod() определение в Cat, ваш main можно сказать

testClassMethod();

вызвать метод, определенный в Animal, Но вы больше не можете этого делать. Да, вы все равно можете позвонить, указав точное имя:

Animal.testClassMethod();

так что это не совсем скрыто. Но учтите, что люди, которые пишут языковые стандарты, должны придумывать названия для некоторых понятий, которые могут не совсем соответствовать значениям, которые мы даем словам в некомпьютерном мире, поэтому иногда лучше всего подойти ближе. Вы не можете пытаться воспринимать терминологию буквально. Семестр hidden я полагаю, что имеет формальное определение где-то в JLS; и это означает, что когда вы видите термин, используемый в JLS, это означает, что то, что JLS определяет для него, ни больше, ни меньше.

Другие вопросы по тегам