Почему невозможно переопределить статические методы?
Если возможно, пожалуйста, используйте пример.
java
static
overriding
static-methods
sgokhales
источник
источник
Parent p = new Child()
иp.childOverriddenStaticMethod()
компилятор разрешит егоParent.childOverriddenStaticMethod()
, взглянув на ссылочный тип.Ответы:
Переопределение зависит от наличия экземпляра класса. Смысл полиморфизма в том, что вы можете создать подкласс класса, и объекты, реализующие эти подклассы, будут иметь разные поведения для одних и тех же методов, определенных в суперклассе (и переопределенных в подклассах). Статический метод не связан ни с одним экземпляром класса, поэтому концепция не применима.
На разработку Java повлияли два фактора. Одна из них была связана с производительностью: было много критики по поводу того, что Smalltalk слишком медленный (сборщик мусора и полиморфные вызовы являются частью этого), и создатели Java были полны решимости этого избежать. Другим было решение, что целевой аудиторией для Java были разработчики C ++. Заставить статические методы работать так, как они это делали, было полезно для программистов на C ++, а также очень быстро, потому что не нужно ждать времени выполнения, чтобы выяснить, какой метод вызывать.
источник
objects
) допускают перегрузку методов.obj.staticMethod()
), который разрешен и использует типы времени компиляции. Когда статический вызов выполняется в нестатическом методе класса, «текущий» объект может быть производным типом класса, но статические методы, определенные для производных типов, не учитываются (они относятся к типу времени выполнения). иерархии).Лично я считаю, что это недостаток в дизайне Java. Да, да, я понимаю, что нестатические методы присоединяются к экземпляру, а статические методы - к классу и т. Д. И т. Д. Тем не менее рассмотрим следующий код:
Этот код не будет работать так, как вы могли бы ожидать. А именно, SpecialEmployee получают 2% бонус, как и обычные сотрудники. Но если вы удалите «статичные», SpecialEmployee получит бонус 3%.
(Следует признать, что этот пример является плохим стилем кодирования, поскольку в реальной жизни вы, вероятно, захотите, чтобы бонусный множитель находился где-то в базе данных, а не был жестко закодирован. Но это только потому, что я не хотел увязывать пример с большим количеством кода не имеет отношения к делу.)
Мне кажется вполне вероятным, что вы можете сделать getBonusMultiplier статическим. Возможно, вы хотите иметь возможность отображать бонусный множитель для всех категорий сотрудников без необходимости иметь экземпляр сотрудника в каждой категории. Какой смысл искать такие примеры? Что, если мы создаем новую категорию сотрудников, и у нас еще нет назначенных сотрудников? Это вполне логично, статическая функция.
Но это не работает.
И да, да, я могу придумать множество способов переписать приведенный выше код, чтобы он работал. Моя точка зрения не в том, что это создает неразрешимую проблему, а в том, что она создает ловушку для неосторожного программиста, потому что язык не ведет себя так, как я думаю, разумный человек ожидал бы.
Возможно, если бы я попытался написать компилятор для языка ООП, я бы быстро понял, почему реализовать его так, чтобы статические функции могли быть переопределены, было бы трудно или невозможно.
Или, возможно, есть какая-то веская причина, почему Java ведет себя так. Кто-нибудь может указать на преимущество в этом поведении, некоторую категорию проблем, которая облегчается этим? Я имею в виду, не просто указывайте мне на спецификацию языка Java и говорите: «Посмотрите, это задокументировано, как оно себя ведет». Я знаю это. Но есть ли веская причина, почему он ДОЛЖЕН вести себя так? (Помимо очевидного «заставить его работать правильно, было слишком сложно» ...)
Обновить
@VicKirk: Если вы имеете в виду, что это «плохой дизайн», потому что он не соответствует тому, как Java обрабатывает статику, я отвечаю: «Ну, конечно, конечно». Как я уже говорил в моем оригинальном сообщении, это не работает. Но если вы имеете в виду, что это плохой дизайн в том смысле, что с языком, в котором это работает, было бы что-то принципиально неправильное, то есть где статика могла бы быть переопределена, как виртуальные функции, что это каким-то образом внесло бы двусмысленность, или было бы невозможно эффективно или что-то подобное, я отвечаю: «Почему? Что не так с концепцией?»
Я думаю, что пример, который я привожу, очень естественен для желающих. У меня есть класс, у которого есть функция, которая не зависит от каких-либо данных экземпляра, и которую я мог бы очень разумно вызывать независимо от экземпляра, а также желая вызывать из метода экземпляра. Почему это не должно работать? Я сталкивался с этой ситуацией довольно много раз за эти годы. На практике я обхожу это, делая функцию виртуальной, а затем создавая статический метод, единственная цель которого в жизни - быть статическим методом, который передает вызов виртуальному методу с фиктивным экземпляром. Это кажется очень окольным способом добраться туда.
источник
someStatic()
а B расширяет A, тоB.someMethod()
связывается с методом в A. Если я впоследствии добавлюsomeStatic()
к B, вызывающий код все еще будет вызываться,A.someStatic()
пока я не перекомпилирую вызывающий код. Также меня удивило, чтоbInstance.someStatic()
используется объявленный тип bInstance, а не тип времени выполнения, потому что он связывается при компиляции, а не по ссылке, поэтомуA bInstance; ... bInstance.someStatic()
вызывает A.someStatic (), если существует B.someStatic ().Короткий ответ: это вполне возможно, но Java этого не делает.
Вот некоторый код, который иллюстрирует текущее состояние дел в Java:
Файл
Base.java
:Файл
Child.java
:Если вы запустите это (я сделал это на Mac, из Eclipse, используя Java 1.6), вы получите:
Здесь единственные случаи, которые могут быть неожиданностью (и о чем идет речь), являются первым случаем:
«Тип времени выполнения не используется для определения того, какие статические методы вызываются, даже когда они вызываются с помощью экземпляра объекта (
obj.staticMethod()
)».и последний случай:
«При вызове статического метода из метода объекта класса выбран статический метод, доступный из самого класса, а не из класса, определяющего тип времени выполнения объекта».
Вызов с экземпляром объекта
Статический вызов разрешается во время компиляции, тогда как вызов нестатического метода разрешается во время выполнения. Обратите внимание, что хотя статические методы наследуются (от родителя), они не переопределяются (дочерними). Это может быть сюрпризом, если вы ожидаете иначе.
Вызов из метода объекта
Вызовы методов объекта разрешаются с использованием типа времени выполнения, но вызовы статических ( классовых ) методов разрешаются с использованием типа времени объявления (объявленного).
Изменение правил
Чтобы изменить эти правила, чтобы при последнем вызове в вызываемом примере
Child.printValue()
статические вызовы должны были быть предоставлены с типом во время выполнения, а не компилятором, разрешающим вызов во время компиляции с объявленным классом объекта (или контекст). Статические вызовы могут затем использовать (динамическую) иерархию типов для разрешения вызова, так же, как вызовы объектных методов делают сегодня.Это легко выполнимо (если мы изменили Java: -O), и это вовсе не неразумно, однако, у него есть некоторые интересные соображения.
Основное соображение заключается в том, что нам нужно решить, какие статические вызовы методов должны делать это.
На данный момент в Java есть такая «причуда» в языке, при которой
obj.staticMethod()
вызовы заменяютсяObjectClass.staticMethod()
вызовами (обычно с предупреждением). [ Примечание:ObjectClass
это тип времени компиляцииobj
.] Это были бы хорошие кандидаты для переопределения таким способом, принимая тип времени выполненияobj
.Если бы мы сделали это, это бы затруднило чтение тел методов: статические вызовы в родительском классе потенциально могли бы быть динамически «перенаправлены». Чтобы избежать этого, нам пришлось бы вызывать статический метод с именем класса - и это делает вызовы более очевидно разрешенными с помощью иерархии типов времени компиляции (как сейчас).
Другие способы вызова статического метода более хитры: они
this.staticMethod()
должны означать то же самоеobj.staticMethod()
, что и тип во время выполненияthis
. Однако это может вызвать некоторые проблемы с существующими программами, которые вызывают (очевидно локальные) статические методы без декорации (что, возможно, эквивалентноthis.method()
).Так что насчет неукрашенных звонков
staticMethod()
? Я предлагаю сделать то же самое, что и сегодня, и использовать контекст локального класса, чтобы решить, что делать. В противном случае возникнет великое замешательство. Конечно, это означает, чтоmethod()
это означалоthis.method()
бы, если быmethod
был нестатический метод, иThisClass.method()
если быmethod
был статический метод. Это еще один источник путаницы.Другие соображения
Если мы изменили это поведение (и сделали статические вызовы потенциально динамически нелокальным), мы, вероятно , захотите пересмотреть смысл
final
,private
аprotected
также отборочные наstatic
методах класса. Тогда нам всем придется привыкнуть к тому факту, чтоprivate static
иpublic final
методы не переопределяются и поэтому могут быть безопасно разрешены во время компиляции и «безопасны» для чтения как локальные ссылки.источник
На самом деле мы были не правы.
Несмотря на то, что Java не позволяет вам переопределять статические методы по умолчанию, если вы внимательно изучите документацию по классам классов и методов в Java, вы все равно сможете найти способ эмулировать переопределение статических методов с помощью следующего обходного пути:
Результирующий вывод:
что мы пытались достичь :)
Даже если мы объявим третью переменную Carl как RegularEmployee и назначим ей экземпляр SpecialEmployee, у нас все равно останется вызов метода RegularEmployee в первом случае и вызов метода SpecialEmployee во втором случае
просто посмотрите на консоль вывода:
;)
источник
Статические методы обрабатываются JVM как глобальные, они вообще не привязаны к экземпляру объекта.
Концептуально это было бы возможно, если бы вы могли вызывать статические методы из объектов класса (как в языках, таких как Smalltalk), но это не так в Java.
РЕДАКТИРОВАТЬ
Вы можете перегрузить статический метод, это нормально. Но вы не можете переопределить статический метод, потому что класс не является первоклассным объектом. Вы можете использовать отражение, чтобы получить класс объекта во время выполнения, но полученный вами объект не параллелен иерархии классов.
Вы можете размышлять над классами, но это останавливается там. Вы не вызываете статический метод, используя
clazz1.staticMethod()
, но используяMyClass.staticMethod()
. Статический метод не привязан к объекту, и поэтому в статическом методе нет ни понятия,this
ниsuper
статического метода. Статический метод - это глобальная функция; как следствие, также отсутствует понятие полиморфизма, и поэтому переопределение метода не имеет смысла.Но это могло бы быть возможно, если бы во время выполнения
MyClass
был объект, для которого вы вызываете метод, как в Smalltalk (или, может быть, JRuby, как предполагает один комментарий, но я ничего не знаю о JRuby).Ах да ... еще одна вещь. Вы можете вызывать статический метод через объект,
obj1.staticMethod()
но это действительно синтаксический сахар дляMyClass.staticMethod()
и его следует избегать. Это обычно вызывает предупреждение в современной IDE. Я не знаю, почему они позволили этот ярлык.источник
clazz2 instanceof clazz1
правильного использования вы можете вместо этого использоватьclass2.isAssignableFrom(clazz1)
, что, я считаю, вернет true в вашем примере.Переопределение метода стало возможным благодаря динамической диспетчеризации , что означает, что объявленный тип объекта не определяет его поведение, а скорее тип времени выполнения:
Хотя оба
lassie
иkermit
объявлены как объекты типаAnimal
, их поведение (метод.speak()
) варьируется, поскольку динамическая диспетчеризация будет связывать вызов метода.speak()
только с реализацией во время выполнения, а не во время компиляции.Теперь вот где
static
ключевое слово начинает иметь смысл: слово «статический» является антонимом слова «динамический». Поэтому причина, по которой вы не можете переопределить статические методы, заключается в том, что нет динамической диспетчеризации статических элементов - потому что статический буквально означает «не динамический». Если они отправляются динамически (и, следовательно, могут быть переопределены),static
ключевое слово больше не будет иметь смысла.источник
Да. Практически Java допускает переопределение статического метода, и теоретически Нет, если вы переопределяете статический метод в Java, тогда он будет скомпилирован и работать гладко, но потеряет полиморфизм, который является базовым свойством Java. Вы будете читать везде, что вы не можете попробовать самостоятельно скомпилировать и запустить. вы получите ответ. Например, если у вас есть Class Animal и статический метод eat (), и вы переопределяете этот статический метод в его подклассе, то вы называете его Dog. Тогда, когда бы вы ни назначали объект Dog для ссылки на животных и вызывали eat () в соответствии с Java, должна быть вызвана функция eat () собаки, но в статических переопределенных животных будет вызываться функция eat ().
Согласно принципу полиморфизма Java, вывод должен быть
Dog Eating
.Но результат был другим, потому что для поддержки полиморфизма Java использует Late Binding, что означает, что методы вызываются только во время выполнения, но не в случае статических методов. В статических методах компилятор вызывает методы во время компиляции, а не во время выполнения, поэтому мы получаем методы в соответствии со ссылкой, а не со ссылкой на объект, содержащий ссылку, поэтому вы можете сказать, что практически он поддерживает статическое переопределение, но теоретически это не так. «т.
источник
переопределение зарезервировано для членов экземпляра для поддержки полиморфного поведения. статические члены класса не принадлежат конкретному экземпляру. вместо этого статические члены принадлежат классу, и в результате переопределение не поддерживается, поскольку подклассы наследуют только защищенные и открытые члены экземпляра, а не статические члены. Вы можете захотеть определить внутреннюю и исследовательскую фабрику и / или шаблоны разработки стратегии для оценки альтернативного подхода.
источник
В Java (и во многих языках ООП, но я не могу говорить за всех; а некоторые вообще не имеют статики) все методы имеют фиксированную сигнатуру - параметры и типы. В виртуальном методе подразумевается первый параметр: ссылка на сам объект и при вызове изнутри объекта компилятор автоматически добавляет
this
.Для статических методов нет никакой разницы - они все еще имеют фиксированную подпись. Однако, объявив метод статическим, вы явно заявили, что компилятор не должен включать параметр подразумеваемого объекта в начале этой сигнатуры. Поэтому любой другой код, который вызывает это, не должен пытаться поместить ссылку на объект в стек . Если это так, то выполнение метода не будет работать, так как параметры будут в неправильном месте - смещены на единицу - в стеке.
Из-за этой разницы между ними; виртуальные методы всегда имеют ссылку на объект контекста (то есть
this
), поэтому в кучи можно ссылаться на все, что принадлежит этому экземпляру объекта. Но со статическими методами, поскольку не передается ссылка, этот метод не может получить доступ к переменным и методам объекта, так как контекст неизвестен.Если вы хотите, чтобы Java изменила определение так, чтобы контекст объекта передавался для каждого метода, статического или виртуального, то в сущности вы бы имели только виртуальные методы.
Как кто-то спросил в комментарии к оперу - какова ваша причина и цель, чтобы хотеть эту функцию?
Я не знаю много Ruby, так как это было упомянуто OP, я провел некоторые исследования. Я вижу, что в классах Ruby действительно особый вид объектов, и можно создавать (даже динамически) новые методы. Классы являются полными объектами классов в Ruby, их нет в Java. Это то, что вы должны будете принять при работе с Java (или C #). Это не динамические языки, хотя C # добавляет некоторые формы динамических. На самом деле, в Ruby, насколько я мог найти, нет «статических» методов - в этом случае это методы объекта класса singleton. Затем вы можете переопределить этот синглтон новым классом, и методы в предыдущем объекте класса будут вызывать методы, определенные в новом классе (правильно?). Таким образом, если вы вызываете метод в контексте исходного класса, он все равно будет выполнять только исходную статику, но вызов метода в производном классе вызовет методы из родительского или подкласса. Интересно, и я вижу некоторую ценность в этом. Требуется другой образ мыслей.
Так как вы работаете в Java, вам нужно будет приспособиться к такому образу действий. Почему они это сделали? Ну, возможно, чтобы улучшить производительность в то время на основе технологии и понимания, которые были доступны. Компьютерные языки постоянно развиваются. Вернитесь достаточно далеко, и ООП не будет. В будущем появятся другие новые идеи.
РЕДАКТИРОВАТЬ : еще один комментарий. Теперь, когда я вижу различия и, будучи самим разработчиком Java / C #, я могу понять, почему ответы, которые вы получаете от разработчиков Java, могут сбивать с толку, если вы работаете с таким языком, как Ruby.
static
Методы Java не совпадают сclass
методами Ruby . Разработчикам Java будет сложно понять это, так же как и тем, кто работает в основном с таким языком, как Ruby / Smalltalk. Я могу видеть, как это могло бы сильно сбить с толку тем фактом, что Java также использует «метод класса» как еще один способ говорить о статических методах, но этот же термин по-разному используется в Ruby. В Java нет методов класса Ruby (извините); Ruby не имеет статических методов в стиле Java, которые на самом деле являются просто старыми функциями процедурного стиля, как в C.Кстати - спасибо за вопрос! Сегодня я узнал что-то новое о методах класса (стиль Ruby).
источник
Ну ... ответ НЕТ, если вы думаете с точки зрения того, как переопределенный метод должен вести себя в Java. Но вы не получите никакой ошибки компилятора, если попытаетесь переопределить статический метод. Это означает, что если вы попытаетесь переопределить, Java не остановит вас; но вы, конечно, не получите тот же эффект, что и для нестатических методов. Переопределение в Java просто означает, что конкретный метод будет вызываться на основе типа времени выполнения объекта, а не типа его времени компиляции (что имеет место с переопределенными статическими методами). Хорошо ... есть предположения, почему они ведут себя странно? Поскольку они являются методами класса и, следовательно, доступ к ним всегда разрешается во время компиляции только с использованием информации о типе времени компиляции.
Пример : давайте попробуем посмотреть, что произойдет, если мы попробуем переопределить статический метод:
Выход : -
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod
Обратите внимание на вторую строку вывода. Если бы staticMethod был переопределен, эта строка должна была бы быть идентичной третьей строке, поскольку мы вызываем staticMethod () для объекта Runtime Type как «SubClass», а не как «SuperClass». Это подтверждает, что статические методы всегда разрешаются с использованием только их информации о типе времени компиляции.
источник
В общем случае не имеет смысла разрешать «переопределение» статических методов, поскольку не было бы хорошего способа определить, какой из них вызывать во время выполнения. Если взять пример Employee, если мы вызовем RegularEmployee.getBonusMultiplier () - какой метод должен быть выполнен?
В случае Java можно представить определение языка, в котором можно «переопределить» статические методы, если они вызываются через экземпляр объекта. Тем не менее, все, что нужно сделать, это заново реализовать обычные методы класса, добавив избыточность в язык, не добавляя никакой выгоды.
источник
Переопределением мы можем создать полиморфную природу в зависимости от типа объекта. Статический метод не имеет отношения к объекту. Так что Java не может поддерживать переопределение статического метода.
источник
Мне нравится и двойной комментарий Джея ( https://stackoverflow.com/a/2223803/1517187 ).
Я согласен, что это плохой дизайн Java.
Многие другие языки поддерживают переопределение статических методов, как мы видели в предыдущих комментариях. Я чувствую, что Джей также пришел на Яву из Delphi, как и я.
Delphi (Object Pascal) был первым языком, реализующим ООП.
Очевидно, что многие люди имели опыт работы с этим языком, поскольку в прошлом он был единственным языком для написания коммерческих продуктов с графическим интерфейсом. И - да, мы могли бы в Delphi переопределить статические методы. На самом деле статические методы в Delphi называются «методами класса», в то время как Delphi придерживалась другого понятия «статические методы Delphi», которые были методами с ранним связыванием. Чтобы переопределить методы, которые вам пришлось использовать с поздним связыванием, объявите «виртуальную» директиву. Так что это было очень удобно и интуитивно понятно, и я ожидал этого на Java.
источник
Что хорошего в этом, чтобы переопределить статические методы. Вы не можете вызывать статические методы через экземпляр.
РЕДАКТИРОВАТЬ: кажется, что из-за неудачного надзора в языковой дизайн, вы можете вызывать статические методы через экземпляр. Обычно никто не делает это. Виноват.
источник
variable.staticMethod()
, вместо тогоClass.staticMethod()
, гдеvariable
переменная с объявленным типомClass
. Я согласен, что это плохой языковой дизайн.Переопределение в Java просто означает, что конкретный метод будет вызываться в зависимости от типа объекта во время выполнения, а не от его типа во время компиляции (что имеет место в случае переопределенных статических методов). Так как статические методы являются методами класса, они не являются методами экземпляра, поэтому они не имеют никакого отношения к тому, какая ссылка указывает на какой объект или экземпляр, потому что из-за природы статического метода он принадлежит определенному классу. Вы можете переопределить его в подклассе, но этот подкласс не будет ничего знать о статических методах родительского класса, потому что, как я сказал, он специфичен только для того класса, в котором он был объявлен. Доступ к ним с использованием ссылок на объекты - это просто дополнительная свобода, предоставляемая разработчиками Java, и мы, конечно, не должны думать о том, чтобы прекращать эту практику только тогда, когда они ограничивают ее более подробными данными и примерами. http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html
источник
Переопределив, вы достигните динамического полиморфизма. Когда вы говорите о переопределении статических методов, слова, которые вы пытаетесь использовать, противоречивы.
Статика говорит - время компиляции, переопределение используется для динамического полиморфизма. Оба противоположны по своей природе и, следовательно, не могут быть использованы вместе.
Динамическое полиморфное поведение возникает, когда программист использует объект и обращается к методу экземпляра. JRE отобразит разные методы экземпляров разных классов в зависимости от того, какой тип объекта вы используете.
Когда вы говорите о переопределении статических методов, мы обращаемся к статическим методам, используя имя класса, которое будет связано во время компиляции, поэтому нет понятия связывания методов во время выполнения со статическими методами. Таким образом, сам термин «переопределение» статических методов не имеет никакого значения.
Примечание: даже если вы обращаетесь к методу класса с помощью объекта, все же Java-компилятор достаточно умен, чтобы это выяснить, и будет выполнять статическое связывание.
источник
Box.createBox
имеет больше смысла, чемBoxFactory.createBox
, и является неизбежным шаблоном, когда нужно проверять конструкцию ошибок, не выбрасывая исключения (конструкторы не могут потерпеть неудачу, они могут только убить процесс / throw исключение), тогда как статический метод может возвращать ноль при сбое или даже принимать обратные вызовы об успехе / ошибке, чтобы написать что-то вроде hastebin.com/codajahati.java .Ответ на этот вопрос прост: метод или переменная, помеченная как статическая, принадлежит только классу, поэтому статический метод нельзя наследовать в подклассе, поскольку он принадлежит только суперклассу.
источник
Простое решение: использовать экземпляр Singleton. Это позволит переопределения и наследования.
В моей системе у меня есть класс SingletonsRegistry, который возвращает экземпляр для переданного класса. Если экземпляр не найден, он создается.
Haxe языковой класс:
источник
Singleton.get()
, Реестр - это просто накладные расходы, и он исключает GC для классов.Статический метод, переменная, блок или вложенный класс принадлежит всему классу, а не объекту.
Метод в Java используется для представления поведения объекта / класса. Здесь, поскольку метод является статическим (т. Е. Статический метод используется для представления поведения только класса.) Изменение / переопределение поведения всего класса нарушит феномен одного из фундаментальных элементов объектно-ориентированного программирования, то есть высокой сплоченности , (помните, конструктор - это особый метод в Java.)
Высокая сплоченность - у одного класса должна быть только одна роль. Например: класс автомобилей должен производить только автомобильные объекты, а не велосипед, грузовики, самолеты и т. Д. Но класс автомобилей может иметь некоторые особенности (поведение), которые принадлежат только ему.
Поэтому при разработке языка программирования Java. Разработчики языка решили позволить разработчикам сохранять некоторые поведения класса при себе, делая метод статичным по своей природе.
Приведенный ниже фрагмент кода пытается переопределить статический метод, но не встретит никакой ошибки компиляции.
Это потому, что здесь мы не переопределяем метод, а просто объявляем его заново . Java позволяет повторно объявить метод (статический / нестатический).
Удаление статического ключевого слова из метода getVehileNumber () класса Car приведет к ошибке компиляции, поскольку мы пытаемся изменить функциональность статического метода, который принадлежит только классу Vehicle.
Кроме того, если getVehileNumber () объявлен как final, код не будет компилироваться, поскольку ключевое слово final ограничивает программиста от повторного объявления метода.
В целом, это зависит от разработчиков программного обеспечения, где использовать статические методы. Лично я предпочитаю использовать статические методы для выполнения некоторых действий без создания какого-либо экземпляра класса. Во-вторых, скрыть поведение класса от внешнего мира.
источник
Вот простое объяснение. Статический метод связан с классом, а метод экземпляра связан с конкретным объектом. Переопределения позволяют вызывать различные реализации переопределенных методов, связанных с конкретным объектом. Так что нелогично переопределять статический метод, который даже не связан с объектами, но сам класс в первую очередь. Таким образом, статические методы не могут быть переопределены в зависимости от того, какой объект их вызывает, они всегда будут связаны с классом, в котором они были созданы.
источник
public abstract IBox createBox();
понятному интерфейсу IBox? Box может реализовать IBox для переопределения createBox и иметь результат создания объекта в допустимом IBox, в противном случае вернуть ноль. Конструкторы не могут возвращать «ноль», и поэтому вы вынуждены (1) использовать исключения ВЕЗДЕ (что мы делаем сейчас) или (2) создавать фабричные классы, которые делают то, что я говорил ранее, но таким образом, что это не имеет смысла для новичков или экспертов Java (что мы и делаем сейчас). Статические нереализованные методы решают эту проблему.Теперь, увидев приведенные выше ответы, все знают, что мы не можем переопределить статические методы, но не следует неправильно понимать концепцию доступа к статическим методам из подкласса .
Например, см. Ниже код: -
Вывод:-
Спасибо
источник
Следующий код показывает, что это возможно:
источник
osm
-OverridenStaticMeth
нетOverrideStaticMeth
.