статические методы и полиморфизм


У меня есть простой вопрос, на который я просто не могу найти хороший ответ. Почему следующая программа Java отображает 20? Я бы предпочел подробный ответ,если это возможно.

class Something{
    public int x;
    public Something(){
        x=aMethod();
    }
    public static int aMethod(){
        return 20;
    }
}
class SomethingElse extends Something{
    public static int aMethod(){
        return 40;
    }
    public static void main(String[] args){
        SomethingElse m;
        m=new SomethingElse();
        System.out.println(m.x);
    }
}
3 3

3 ответа:

Наследование для статических методов работает иначе, чем для нестатических. В частности, статический метод суперкласса не переопределяется подклассом. Результат вызова статического метода зависит от класса объекта, на который он вызывается. Переменная x создается во время создания объекта Something, и поэтому для определения ее значения вызывается статический метод класса (Something).

Рассмотрим следующий код:

public static void main(String[] args){
  SomethingElse se = new SomethingElse();
  Something     sg = se;
  System.out.println(se.aMethod());
  System.out.println(sg.aMethod());
}

Он будет корректно печатать 40, 20 как каждый класс объектов вызывает свой собственный статический метод. документация Java описывает это поведение в части скрытие статических методов.

Потому что полиморфизм применим только к методам экземпляра.

Метод static aMethod, вызываемый здесь

public Something(){
    x=aMethod();
}

Относится к aMethod, объявленному в Something.

Потому что int x объявлен в классе Something. Когда вы создаете объект SomethingElse, Вы сначала создаете объект Something (который должен установить x, и он использует aMethod() из Something вместо SomethingElse (потому что вы создаете Something)). Это происходит потому, что аметод() статичен, а полиморфизм не работает для статических методов. Затем, когда вы печатаете x из m, вы печатаете 20, так как вы никогда не изменяли значение x.