в классе наследнике определен статический метод такой же как родительском java

Переопределение статического метода в Java

В Java нельзя переопределять статические методы. Но почему работает следующий код:

На печать выводится «B». Все выглядит так, как будто это переопределение. Потому что при перегрузке я должна была бы что-то изменить в сигнатуре метода. Но нет, я ничего не меняла.

Аннотацию «override» не могу поставить над методом.

в классе наследнике определен статический метод такой же как родительском java. Смотреть фото в классе наследнике определен статический метод такой же как родительском java. Смотреть картинку в классе наследнике определен статический метод такой же как родительском java. Картинка про в классе наследнике определен статический метод такой же как родительском java. Фото в классе наследнике определен статический метод такой же как родительском java

2 ответа 2

Переопределение метода:

Переопределение метода (Method overriding) это возможность языка позволяющая подклассу или дочернему элементу классу обеспечивать специфическую реализацию метода, который уже реализовали в одном из супер-классов или родительском классе. Переопределение выглядит так:

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

Сокрытие метода:

Сокрытие методов, грубо говоря, представляет из себя «перекрытие» методом текущего класса, метода родительского класса. Выглядит это следующим образом:

Важно отметить, что перекрытие требует таких же правил как и переопределение метода.

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

Рассмотрим использование таких методов в своих классах

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

Поскольку теперь у класса Dog появился «свой метод» voice() он перекрывает метод унаследованный от Animal

Хочу дополнить тем, что перекрытие работает не только с методами класса, но и с его полями. Небольшой пример:

Источник

Наследуются ли статические методы в Java?

Я читал руководство Программиста По Сертификация Java™ SCJP Халид Моголов.

в главе наследования он объясняет, что

наследование членов тесно связано с их объявленным доступность. Если элемент суперкласса доступен по его простому имени в подклассе (без использования какого-либо дополнительного синтаксиса, такого как super), это член считается унаследованным

Он также упоминает, что статические методы не наследуются. Но код ниже отлично подходит:

применимо ли объяснение книги только к методам экземпляра?

14 ответов

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

подкласс наследует все открытые и защищенные члены своего родителя, независимо от того, в каком пакете находится подкласс. Если подкласс находится в том же пакете, что и его родитель, он также наследует члены package-private родителя. Наследуемые элементы можно использовать как есть, заменять их, скрывать или дополнять новыми члены

единственное отличие от унаследованных статических (class) методов и унаследованных нестатических (instance) методов заключается в том, что при написании нового статического метода с той же сигнатурой старый статический метод просто скрыт, а не переопределен.

с страница о разнице между переопределением и скрытием.

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

Если это то, что книга действительно говорит, это неправильно.[1]

8.4.8 наследование, переопределение и сокрытие

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

m является членом прямого суперкласса C.

м. public, protected или объявленная с выходом пакета в пакет С.

ни один метод, объявленный в C, не имеет подписи, которая является подсигнализацией (§8.4.2) подписи m.

[1] это не сказано в моей копии, 1-е издание, 2000.

вы можете испытать разницу в следующем коде, который немного изменяет ваш код.

это связано с тем, что статические методы являются методами класса.

A. display () и B. display () вызовут метод своих соответствующих классов.

B. display () работает, потому что статическое объявление делает метод/член принадлежащим классу, а не какому-либо конкретному экземпляру класса (aka Object). Вы можете прочитать больше об этом здесь.

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

эта концепция не так проста, как кажется. Мы можем получить доступ к статическим членам без наследования, который имеет отношения. Мы можем получить доступ к статическим членам, также расширив родительский класс. Это не означает, что это ISA-отношение (наследование). На самом деле статические члены принадлежат классу, а static не является модификатором доступа. Пока модификаторы доступа разрешают доступ к статическим членам, мы можем использовать их в других классах. Например, если он публичный, то он будет доступен внутри такой же пакет и также вне пакета. Для частных мы не можем использовать его нигде. По умолчанию мы можем использовать только внутри пакета. Но для защиты мы должны расширить супер класс. Таким образом, получение статического метода в другой класс не зависит от статичности. Это зависит от модификаторов доступа. Таким образом, на мой взгляд, статические члены могут получить доступ, если модификаторы доступа позволяют. В противном случае, мы можем использовать их, как мы используем по Хаса-связи. И имеет отношение не к наследованию. Снова мы не можем переопределить статический метод. Если мы можем использовать другой метод, но не можем его переопределить, то это hasa-relation. Если мы не сможем их отменить, это не будет наследством.Таким образом, автор был на 100% прав.

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

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

но также верно, что статическая функция-член, не участвуют в динамической привязки. Если подпись этого статического метода одинакова как в Родительском, так и в дочернем классе, то применяется концепция затенения, а не полиморфизм.

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

многие озвучили свой ответ в словах. Это расширенное объяснение в коде:

таким образом, это вывод:

статические методы в Java наследуются, но не могут быть переопределены. Если вы объявляете тот же метод в подклассе, вы скрываете метод суперкласса вместо его переопределения. Статические методы не являются полиморфными. Во время компиляции статический метод будет статически связан.

вы получите следующее:

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

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

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

Источник

10 заметок о модификаторе Static в Java

Статические поля

Статический блок

Статический метод

Статический класс в Java

Что должен знать каждый программист о модификаторе Static в Java

Вы НЕ можете получить доступ к НЕ статическим членам класса, внутри статического контекста, как вариант, метода или блока. Результатом компиляции приведенного ниже кода будет ошибка:

В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких как «состояние гонки» (race condition).

Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый объект для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы как нельзя лучше подходят в качестве методов-фабрик ( factory ), и методов-утилит ( utility ). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утилиты в Java финализированы ( final ).

Другим важным моментом является то, что вы НЕ можете переопределять ( Override ) статические методы. Если вы объявите такой же метод в классе-наследнике ( subclass ), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса ( superclass ) вместо переопределения. Это явление известно как сокрытие методов ( hiding methods ). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

Внутри родительского класса/статического метода

Модификатор static также может быть объявлен в статичном блоке, более известным как «Статический блок инициализации» ( Static initializer block ), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных или не статических методов, которые связываются во время исполнения на реальном объекте. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности или необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утилиты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.

На этом всё. Все вышеперечисленные пункты о модификаторе static в Java обязан знать каждый программист. В данной статье была рассмотрена базовая информация о статических переменных, полях, методах, блоках инициализации и импорте. В том числе некоторые важные свойства, знание которых является критичным при написании и понимании программ на Java. Я надеюсь, что каждый разработчик доведёт свои навыки использования статических концептов до совершенства, т.к. это очень важно для серьёзного программирования.»

Источник

В классе наследнике определен статический метод такой же как родительском java

в классе наследнике определен статический метод такой же как родительском java. Смотреть фото в классе наследнике определен статический метод такой же как родительском java. Смотреть картинку в классе наследнике определен статический метод такой же как родительском java. Картинка про в классе наследнике определен статический метод такой же как родительском java. Фото в классе наследнике определен статический метод такой же как родительском java

Определение

Статическими методами в Java называют такие методы, которые могут быть вызваны без создания экземпляра класса. Например, метод pow () из класса Math является статическим:

Когда следует использовать

Особенности применения

Важным моментом является то, что статические методы переопределять (Override) нельзя. Если объявить такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, то лишь «спрячется» метод суперкласса (superclass) вместо переопределения. Это явление известно как сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

Вывод в консоль:
Внутри родительского класса/статического метода

Код наглядно демонстрирует: несмотря на то, что объект имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И при этом ошибки во время компиляции не возникло!

Статические методы в JVM

Статические методы и переменные хранились в области Permgen до 8-й версии java. Начиная с 8-й версии, они хранятся в новой область памяти, которая называется Metaspace

Примеры применения статических методов

Достоинства и недостатки

Достоинства

Недостатки

Источник

В классе наследнике определен статический метод такой же как родительском java

Ключевое слово static в Java

Например, у него может быть цвет, материал изготовления, форма, он может состоять также из более мелких узлов(вспомогательных приборов) и т.д

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

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

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

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

В качестве примера, рассмотрим метод, который печатает в консоль число, которое передается аргументом в этот метод:

Т.е такой метод не связан с объектом класса, он связан только с классом, в котором объявлен.

А раз он не связан с объектом, то и объект, для использования этого метода, не нужен. Нужен только класс, в котором объявлен этот метод.

Указав модификатор static у поля или метода класса, вы тем самым говорите: это поле или метод принадлежат именно классу.

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

Грубо говоря, если вы объявляете поле класса статическим, то вы как бы расшариваете это поле для всех объектов.

Представьте себе документ, который редактирует несколько пользователей. Если один из пользователй изменяет какое-то слово или абзац, то документ меняется у всех пользователей.

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

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

Где используется static

Ключевое слово static может быть использовано при объявлении:

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

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

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

Если же для работы статического метода передаваемых ему аргументов недостаточно, то это верный признак того, что стоит крепко задуматься: «А должен ли он вообще быть статическим?».

Статические методы применяются также при использовании factory и builder паттернов.

Подробнее об этом в Паттерны.

Создание экземпляров объектов

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

Обычно внутри таких методов добавляется еще какая-то логика или оптимизация.

Наиболее часто используемые значения также кешируются.

Представим для примера, что мы хотим посчитать количество созданных экзмепляров класса:

Но в основном статические поля используются для создания констант:

Про константы и их оформление можно прочесть вот тут.

Статические блоки кода

Инициализация статического блока кода выполняется на этапе загрузки класса, грубо говоря, в момент первого к нему обращения. Благодаря этому статические блоки кода используются тогда, когда необходимо выполнить какую-то логику еще до создания экземпляра объекта.

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

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

Выглядит синтаксис статического блока вот так:

Статических блоков может быть несколько, их выполнение будет происходить в порядке объявления.

Статические блоки можно использовать для инициализации статических полей, например:

Т.е у нас есть некоторый каталог и есть данные для заполнения.

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

Так вот, загрузку драйвера как раз делают в статическом блоке:

Подробнее о порядке выполнения кода при инициализации класса: Порядок инициализации полей класса в Java.

Статические вложенные классы

В Java можно объявить класс внутри другого класса.

Для иллюстрации вышесказанного:

Понятно, что nested класссы принадлежат outer классу, в то время как inner классы принадлежат уже экземпляру объекта класса.

Зачем же вообще нужны nested классы?

Например, вы пишите реализацию связного списка.

Логично, что исходя из этого делать отдельный public класс излишне.

Объявив же в такой ситуации вложенный класс, вы добьетесь сразу нескольких преимуществ:

Логически сгруппируете классы, которые используются в одном месте

Если класс полезен только для одного стороннего класса, то логично ввести его в этот класс и поддерживать вместе.

Это способ привести код к более читабельному и поддерживаемому виду.

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

Это увеличивает инкапсуляцию.

Если вложенный класс используется только внутри стороннего класса, логично скрыть его и использовать лишь внутри. Аналогично с тем, как мы объявляем private поля.

Подробнее о вложенных классах: Вложенные классы в Java.

Как стоит обращаться к статическим полям или методам

Если коротко, то раз поле или метод принадлежит классу, то и обращаться к нему необходимо через имя класса.

Если нужны подробности, то давайте посмотрим на следующий класс, содержащий статическое поле:

Мы хотим обратиться к этому полю, и возникает вопрос: как правильно это сделать?

Есть два рабочих варианта:

Так вот, сразу скажу: забудьте про первый вариант. Да, он рабочий, но делать так не стоит. Более того, это глупо!

Вспомните, что статические поля принадлежат не экземпляру объекта класса, а самому классу. Так зачем вам объект?

Для закрепления приведу следующий пример:

Возьмем класс, описанный выше, и ответим на вопрос: что будет, если мы выполним следующий код:

Ведь мы обращаемся к полю, которое принадлежит классу! А значит обращение будет не к объекту экземпляра, и код, который выполнится будет равнозначен выполнению:

Т.е даже если вы будете обращаться к полю или методу, которое является статическим, через объекты экземпляров, компилятор все равно будет вас исправлять.

Запомните следующее: обращение к статическим методам и полям осуществляется только через имя класса.

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

Т.е при работе с статическими методами override невозможен.

Если вы объявите один и тот же метод в классе-наследнике и в родительском классе, т.е. метод с таким же именем и сигнатурой, вы лишь спрячете метод родительского класса, но не переопределите.

При обращении к статическому методу, который объявлен как в родительском, так и в классе-наследнике, во время компиляции всегда будет вызван метод исходя из типа ссылки, по которой идет обращение к такому полю или методу.

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

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

Что еще надо знать про static модификатор в Java

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

Ключевое слово static может быть использовано при объявлении:

Чаще всего оно применяется для первых двух случаев.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *