Почему мой статический блок позволяет вызывать статический метод родительского класса без использования ссылки на родительский класс?

Насколько я понимаю, обычно статический метод следует вызывать с использованием ссылки на класс или его можно вызывать напрямую без ссылки, если он находится в статическом методе или статическом блоке.

Но применимо ли это, когда статический метод вызывается из статических блоков дочернего класса?

Почему это разрешено, поскольку статические методы не наследуются, это должно быть разрешено только с использованием имени родительского класса?

public abstract class abs {

    /**
     * @param args
     */
    abstract void m();
    static void n(){
        System.out.println("satic method");
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}
class myclass extends abs{

    @Override
    void m() {
        // TODO Auto-generated method stub

    }
    static{
        n();
    }
}

Почему мой статический блок дочернего класса может вызывать статический метод родительского класса без ссылки или имени класса?


person amarnath harish    schedule 25.03.2018    source источник
comment
Статические методы наследуются.   -  person cpp beginner    schedule 25.03.2018
comment
Взгляните на этот вопрос о наследовании статических методов в Java.   -  person Raul Sauco    schedule 25.03.2018


Ответы (5)


Статический метод n() наследуется подклассом myclass, поэтому вы можете вызывать его непосредственно в статическом блоке myclass.

person xingbin    schedule 25.03.2018
comment
разве это не нарушает всей концепции статики, принадлежащей классу, следовательно, не может быть унаследовано? - person amarnath harish; 25.03.2018
comment
comment
Единственная разница между унаследованными статическими (классовыми) методами и унаследованными нестатическими (экземплярными) методами заключается в том, что когда вы пишете новый статический метод с той же сигнатурой, старый статический метод просто скрывается, а не переопределяется. это имеет смысл - person amarnath harish; 25.03.2018
comment
@amarnathharish Такого понятия не существует. Вы ошибаетесь. - person user207421; 29.03.2018

Обычно статический метод следует вызывать с использованием ссылки на класс или его можно вызывать напрямую без ссылки, если он находится в статическом методе или статическом блоке.

Не совсем. Например, метод экземпляра может вызывать статический метод без префикса класса.

В более общем смысле, static члены (поля как методы) должны вызываться с префиксом их класса только потому, что компилятор не может вывести класс, к которому они принадлежат.
Когда вы вызываете статический метод, определенный в родительском классе, из подкласса (и статические методы наследуются в подклассах), вам не нужно добавлять префикс к классу вызова метода, поскольку компилятор делает вывод об этом.

person davidxxx    schedule 25.03.2018
comment
хорошо, у меня есть один вопрос, если статические методы наследуются, что, если у меня также есть другой статический метод в дочернем классе с такими же сигнатурами методов? как компилятор решит это? - person amarnath harish; 25.03.2018
comment
В этом случае метод, определенный в подклассе, затеняет (а не переопределяет) метод, определенный в родительском. Обратите внимание, что это, как правило, плохая практика. Без префикса в контексте класса компилятор выберет метод текущего класса. - person davidxxx; 25.03.2018

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

person Rob    schedule 25.03.2018

Почему это позволяет такое

По наследству.

поскольку статические методы не наследуются

Ты продолжаешь это говорить. Вы ошибаетесь. Из JLS #8.4.8 :

Класс C наследует от своего непосредственного суперкласса все конкретные методы m (как static, так и экземпляр) суперкласса, для которых верно все следующее: ...

Продолжение см. здесь.

person user207421    schedule 29.03.2018

Все члены суперкласса наследуются подклассом, который также включает статические методы.

    class SuperClassA {

    static void superclassmethod() {
        System.out.println("superclassmethod in Superclass ");
    }
}

public class SubClassA extends SuperClassA {
    static {
        superclassmethod();
    }

    public static void main(String[] args) {

    }
}

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

person Nisrin Dhoondia    schedule 28.03.2018
comment
Не существует такой вещи, как переопределение статических методов. - person user207421; 29.03.2018
comment
@ EJP Я имел в виду, что если кто-то пишет в подклассе статический метод с тем же именем, что и у статического метода, существующего в суперклассе, то в этом случае метод подкласса не переопределяет статический метод суперкласса, но скрывает статический метод суперкласса. А также полиморфизм времени выполнения не применяется, когда это статический метод. - person Nisrin Dhoondia; 29.03.2018