6 июл. 2015 г.

Полиморфизм. Поля и статические методы.

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

Полиморфизм поддерживается только для вызова обычных методов. А, например, прямое обращение к полю или статическому методу будет обработано на стадии компиляции. Данная статья это по существу продолжение этой.

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

FS001

Вывод у программы следующий:

FS002

Ссылка sup у нас имеет тип Super и ей присваивается ссылка на объект типа Sub. Обращение к полю происходит по версии ссылки, а обращение к методу по версии объекта. Во втором выводе работают все те же правила, а доступ к полю суперкласса мы получили через метод getSuperClass.

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

Как видно из скриншота ниже прямое обращение к полям компилируется в инструкцию invokespecial.

Обычные же методы – в инстуркцию invokevirtual.

Для sub все происходит точно так же, как и для sup.

FS003

Прошу обратить внимание, что объекты класса Sub фактически имеют два поля str: одно свое, другое унаследованное от суперкласса. Поэтому использовать одно имя для поля базового и производного класса вообще не рекомендуется, потому что это создает путаницу и вообще это плохая идея. Но знать о подобных граблях надо и мы еще к ним вернемся когда будем изучать внутренние классы. Там это может проявиться не явно. Поэтому сейчас мы уже начали готовится к новому удару граблями :)

Теперь перейдем к статическим методам. Статические методы не поддерживают полиморфного поведения.

Еще раз повторюсь, что во первых статические методы правильно вызывать по имени класса, и во вторых статические методы всегда вызываются по версии ссылки.

Демонстрационный код по этому вопросу писать просто лень. К текущему моменту у вас уже и так должно быть ясное представление чем статические методы и поля отличаются от обычных.

4 комментария:

  1. Пример из книги "Философия Java" )

    ОтветитьУдалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить
  3. Автор данного блога, благодарю тебя за данный материал. Я решил пройти весь Java Core, заново, с максимально-детальным пониманием о языке.

    ОтветитьУдалить