Вы не должны помещать какие-либо переменные в интерфейсы.
Черувим
34
Потому что интерфейсы определяют контракты, которые могут быть реализованы различными способами. Значением переменной является реализация.
Черувим
10
Мы, конечно, можем, когда знаем, что все классы, реализующие интерфейс, имеют некоторые постоянные переменные (например, имена полей).
Аникет Тхакур
Является ли хорошей идеей сделать переменную в классе экземпляром интерфейса, который реализует класс? Я слышал это раньше.
Дуг Хауф
Интерфейсы в java следуют принципу ACID, последний из-за нормализации в C. @cherouvim Тип переменной - это реализация, переменная должна быть объявлена со значением или без него, а определение переменной - это значение. Если вы изменяете значение переменной, это не переопределение, это переопределение.
Мрачный
Ответы:
264
Из FAQ по дизайну интерфейса Java от Филиппа Шоу:
Переменные интерфейса являются статическими, потому что интерфейсы Java не могут быть созданы сами по себе; значение переменной должно быть назначено в статическом контексте, в котором не существует ни одного экземпляра. Последний модификатор гарантирует, что значение, присвоенное интерфейсной переменной, является истинной константой, которая не может быть переназначена программным кодом.
Обратите внимание, что абстрактные классы также не могут быть созданы «сами по себе», и у них могут быть переменные экземпляра.
Macias
18
Это объяснение для staticмодификатора является полностью ложным. Публичные переменные экземпляра класса являются частью его интерфейса, и нет никаких причин, по которым они не должны абстрагироваться в Java interface, как методы экземпляра. Неважно, что Java interfaceне может быть создан непосредственно - у вас все еще могут быть экземпляры классов, которые реализуют, interfaceи разумно требовать, чтобы у них была определенная общедоступная переменная экземпляра. Что касается части final, это не дает объяснения вообще - это просто описывает, что finalзначит.
пирократизм
3
Цитата выше лучше в контексте. Это объясняется тем, что «переменные интерфейса предназначены для использования в качестве констант Java». Цитата просто уточняла, почему такая константа будет статичной и окончательной. Это правда, но реальный вопрос заключается в следующем: почему переменные не допускаются как часть реального интерфейса (т. Е. Указываются имена и типы не закрытых членов, которые должны присутствовать в реализующем классе). Если бы они хотели специальные «константы интерфейса», они могли бы использовать новый синтаксис или просто решили, что любые переменные, фактически определенные в интерфейсе, являются константами интерфейса.
Пирократия
6
Интерфейсы не могут иметь переменных экземпляра, чтобы избежать множественного наследования проблем состояния. См. Docs.oracle.com/javase/tutorial/java/IandI/… . Класс не может расширять более одного класса по той же причине.
денис
1
Как внедряются методы по умолчанию и у них есть экземпляр, но переменная экземпляра не поддерживается ...
М.Казем Ахгари
41
Поскольку интерфейс не имеет прямого объекта, единственный способ получить к ним доступ - использовать класс / интерфейс, и, следовательно, поэтому, если переменная интерфейса существует, она должна быть статической, иначе она вообще не будет доступна для внешнего мира. Теперь, поскольку он статичен, он может содержать только одно значение, и любые классы, которые его реализуют, могут изменить его, и, следовательно, все будет беспорядочно.
Следовательно, если вообще есть интерфейсная переменная, она будет неявно статической, конечной и явно публичной !!!
Конечно, переменная экземпляра была бы доступна, если бы она была разрешена в Java interface. Класс будет реализовывать интерфейс, объявляя переменную экземпляра (как того требует интерфейс). Его конструктор (или другой метод) устанавливает переменную экземпляра. Когда экземпляр класса будет создан, вы сможете получить доступ к его переменной экземпляра.
пирократизм
Java позволяет статическим методам с телами существовать в интерфейсе. Они могут получить доступ к статическим переменным. Они просто не могут их изменить, а это значит, что статические функции не могут хранить какие-либо данные
simpleuser
36
public : для доступности для всех классов, так же, как методы, присутствующие в интерфейсе
static : поскольку интерфейс не может иметь объект, interfaceName.variableName может использоваться для ссылки на него или непосредственно на variableName в классе, реализующем его.
Финал : сделать их постоянными. Если 2 класса реализуют один и тот же интерфейс, и вы предоставляете им обоим право изменять значение, конфликт будет иметь место в текущем значении переменной var, поэтому разрешена только одна временная инициализация.
Также все эти модификаторы неявны для интерфейса, вам не нужно указывать ни один из них.
( Это не философский ответ, а скорее практический ). Требование к staticмодификатору очевидно, на что ответили другие. По сути, поскольку интерфейсы не могут быть созданы, единственный способ получить доступ к его полям - сделать их полем класса - static.
Причина, по которой interfaceполя автоматически становятся final(постоянными), состоит в том, чтобы предотвратить случайное изменение значения различными значениями переменной интерфейса в различных реализациях, что может непреднамеренно повлиять на поведение других реализаций. Представьте себе сценарий ниже, где interfaceсвойство явно не стало finalJava:
publicinterfaceActionable{publicstaticboolean isActionable =false;publicvoid performAction();}publicNuclearActionimplementsActionable{publicvoid performAction(){// Code that depends on isActionable variableif(isActionable){// Launch nuclear weapon!!!}}}
Теперь просто подумайте, что произойдет, если другой реализующий класс Actionableизменяет состояние интерфейсной переменной:
publicCleanActionimplementsActionable{publicvoid performAction(){// Code that can alter isActionable state since it is not constant
isActionable =true;}}
Если эти классы загружаются в одной JVM загрузчиком классов, то на поведение класса NuclearActionможет повлиять другой класс, CleanActionкогда его performAction()вызов вызывается после CleanActionвыполнения (в том же потоке или иным образом), что в этом случае может иметь катастрофические последствия. (семантически это).
Поскольку мы не знаем, как каждая реализация interfaceбудет использовать эти переменные, они должны быть неявно final.
В самом деле, без спецификации «Ах» было бы даже не компилировать», так что это на самом деле безопасно использовать переменные (которые неявно являются открытым статическими окончательным) в интерфейсах.
Marco
Я не согласен с ответом, поскольку @Marco сказал, что он даже не скомпилируется. Пока я не нашел другого недостатка, может быть, просто вы не видите написанную static finalдо переменной, которая на самом деле является статической и конечной.
Micer
5
статический - потому что интерфейс не может иметь никакого экземпляра. и последнее - потому что нам не нужно это менять.
«нам не нужно» == «нам не разрешено», не путайте значения.
peterh - Восстановить Монику
3
так как:
Static : поскольку у нас не может быть объектов интерфейсов, мы должны избегать использования переменных-членов уровня объекта и должны использовать переменные уровня класса, то есть static.
Final : чтобы у нас не было неоднозначных значений для переменных (проблема Алмаза - множественное наследование).
А согласно интерфейсу документации это контракт, а не реализация.
Java не допускает абстрактных переменных и / или определений конструктора в интерфейсах. Решение: Просто повесьте абстрактный класс между вашим интерфейсом и вашей реализацией, который только расширяет абстрактный класс следующим образом:
publicinterfaceIMyClass{void methodA();String methodB();Integer methodC();}publicabstractclass myAbstractClass implementsIMyClass{protectedString varA, varB;//Constructor
myAbstractClass(String varA,String varB){this.varA = varA;this.varB =VarB;}//Implement (some) interface methods here or leave them for the concrete classprotectedvoid methodA(){//Do something}//Add additional methods here which must be implemented in the concrete classprotectedabstractLong methodD();//Write some completely new methods which can be used by all subclassesprotectedFloat methodE(){return42.0;}}publicclass myConcreteClass extends myAbstractClass {//Constructor must now be implemented!
myClass(String varA,String varB){super(varA, varB);}//All non-private variables from the abstract class are available here//All methods not implemented in the abstract class must be implemented here}
Вы также можете использовать абстрактный класс без какого-либо интерфейса, если вы уверены, что не хотите реализовывать его вместе с другими интерфейсами позже. Обратите внимание, что вы не можете создать экземпляр абстрактного класса, вы ДОЛЖНЫ его сначала расширить.
(Ключевое слово «protected» означает, что только расширенные классы могут получить доступ к этим методам и переменным.)
Интерфейс - это контракт между двумя сторонами, который является инвариантным, высеченным в камне и, следовательно, окончательным. См. Дизайн по контракту .
В интерфейсе переменные по умолчанию присваиваются модификатором public, static, final access. Так как :
public: иногда случается, что интерфейс может быть помещен в какой-то другой пакет. Таким образом, необходимо получить доступ к переменной из любого места в проекте.
статический: как таковой неполный класс не может создать объект. Таким образом, в проекте нам нужно получить доступ к переменной без объекта, чтобы мы могли получить доступ с помощьюinterface_filename.variable_name
final: предположим, что один интерфейс реализуется многими классами, и все классы пытаются получить доступ и обновить переменную интерфейса. Так что это приводит к непоследовательности изменения данных и влияет на любой другой класс. Так что нужно объявить модификатор доступа с помощью final.
В Javaинтерфейс не позволяет объявлять переменные экземпляра. Использование переменной, объявленной в интерфейсе в качестве переменной экземпляра, вернет ошибку времени компиляции.
Вы можете объявить постоянную переменную, использование static finalкоторой отличается от переменной экземпляра.
Это совершенно неправильно. Компилятор не будет жаловаться, если вы не сделаете его закрытым или защищенным. Под капотом, как уже упоминали другие, они превращаются в публичный статический финал. И я думаю, это довольно очевидно, почему. Потому что интерфейс должен диктовать поведение, а не состояние.
Микаил Абдуллаев
0
Интерфейс может быть реализован любыми классами, и что, если это значение было изменено одним из реализующих его классов, тогда будут введены в заблуждение другие реализующие классы. Интерфейс в основном является ссылкой для объединения двух связанных, но разных сущностей. Поэтому по этой причине объявленная переменная внутри интерфейса будет неявно конечной, а также статической, поскольку интерфейс не может быть создан.
Подумайте о веб-приложении, в котором у вас есть определенный интерфейс, а другие классы реализуют его. Поскольку вы не можете создать экземпляр интерфейса для доступа к переменным, вам нужно иметь статическое ключевое слово. Поскольку оно статическое, любое изменение значения будет отражаться для других экземпляров, которые его реализовали. Поэтому, чтобы предотвратить это, мы определяем их как окончательные.
Только что попробовал в Eclipse, переменная в интерфейсе по умолчанию является окончательной, поэтому вы не можете ее изменить. По сравнению с родительским классом переменные однозначно изменяемы. Зачем? С моей точки зрения, переменная в классе - это атрибут, который будет наследоваться детьми, и дети могут изменять его в соответствии с их реальной потребностью. Напротив, интерфейс определяет только поведение, а не атрибут. Единственная причина для добавления переменных в интерфейс - это использовать их как константы, связанные с этим интерфейсом. Тем не менее, это не очень хорошая практика, согласно следующей выдержке:
«Размещение констант в интерфейсе было популярной техникой в первые дни Java, но теперь многие считают это отвратительным использованием интерфейсов, поскольку интерфейсы должны иметь дело со службами, предоставляемыми объектом, а не его данными. Кроме того, используемые константы классом обычно являются детали реализации, но размещение их в интерфейсе продвигает их к общедоступному API класса ".
Я тоже пробовал либо ставить статичную, либо не делать разницы вообще. Код как ниже:
Ответы:
Из FAQ по дизайну интерфейса Java от Филиппа Шоу:
источник
источник
static
модификатора является полностью ложным. Публичные переменные экземпляра класса являются частью его интерфейса, и нет никаких причин, по которым они не должны абстрагироваться в Javainterface
, как методы экземпляра. Неважно, что Javainterface
не может быть создан непосредственно - у вас все еще могут быть экземпляры классов, которые реализуют,interface
и разумно требовать, чтобы у них была определенная общедоступная переменная экземпляра. Что касается частиfinal
, это не дает объяснения вообще - это просто описывает, чтоfinal
значит.Поскольку интерфейс не имеет прямого объекта, единственный способ получить к ним доступ - использовать класс / интерфейс, и, следовательно, поэтому, если переменная интерфейса существует, она должна быть статической, иначе она вообще не будет доступна для внешнего мира. Теперь, поскольку он статичен, он может содержать только одно значение, и любые классы, которые его реализуют, могут изменить его, и, следовательно, все будет беспорядочно.
Следовательно, если вообще есть интерфейсная переменная, она будет неявно статической, конечной и явно публичной !!!
источник
interface
. Класс будет реализовывать интерфейс, объявляя переменную экземпляра (как того требует интерфейс). Его конструктор (или другой метод) устанавливает переменную экземпляра. Когда экземпляр класса будет создан, вы сможете получить доступ к его переменной экземпляра.public : для доступности для всех классов, так же, как методы, присутствующие в интерфейсе
static : поскольку интерфейс не может иметь объект, interfaceName.variableName может использоваться для ссылки на него или непосредственно на variableName в классе, реализующем его.
Финал : сделать их постоянными. Если 2 класса реализуют один и тот же интерфейс, и вы предоставляете им обоим право изменять значение, конфликт будет иметь место в текущем значении переменной var, поэтому разрешена только одна временная инициализация.
Также все эти модификаторы неявны для интерфейса, вам не нужно указывать ни один из них.
источник
( Это не философский ответ, а скорее практический ). Требование к
static
модификатору очевидно, на что ответили другие. По сути, поскольку интерфейсы не могут быть созданы, единственный способ получить доступ к его полям - сделать их полем класса -static
.Причина, по которой
interface
поля автоматически становятсяfinal
(постоянными), состоит в том, чтобы предотвратить случайное изменение значения различными значениями переменной интерфейса в различных реализациях, что может непреднамеренно повлиять на поведение других реализаций. Представьте себе сценарий ниже, гдеinterface
свойство явно не сталоfinal
Java:Теперь просто подумайте, что произойдет, если другой реализующий класс
Actionable
изменяет состояние интерфейсной переменной:Если эти классы загружаются в одной JVM загрузчиком классов, то на поведение класса
NuclearAction
может повлиять другой класс,CleanAction
когда егоperformAction()
вызов вызывается послеCleanAction
выполнения (в том же потоке или иным образом), что в этом случае может иметь катастрофические последствия. (семантически это).Поскольку мы не знаем, как каждая реализация
interface
будет использовать эти переменные, они должны быть неявноfinal
.источник
Потому что все остальное является частью реализации, и интерфейсы не могут содержать какую-либо реализацию.
источник
Вот решение.
Я думаю, что это одна из причин, почему переменные интерфейса являются статическими.
Не объявляйте переменные внутри интерфейса.
источник
static final
до переменной, которая на самом деле является статической и конечной.статический - потому что интерфейс не может иметь никакого экземпляра. и последнее - потому что нам не нужно это менять.
источник
так как:
Static
: поскольку у нас не может быть объектов интерфейсов, мы должны избегать использования переменных-членов уровня объекта и должны использовать переменные уровня класса, то есть static.Final
: чтобы у нас не было неоднозначных значений для переменных (проблема Алмаза - множественное наследование).А согласно интерфейсу документации это контракт, а не реализация.
ссылка: ответ Абхишека Джайна на квору
источник
Java не допускает абстрактных переменных и / или определений конструктора в интерфейсах. Решение: Просто повесьте абстрактный класс между вашим интерфейсом и вашей реализацией, который только расширяет абстрактный класс следующим образом:
Вы также можете использовать абстрактный класс без какого-либо интерфейса, если вы уверены, что не хотите реализовывать его вместе с другими интерфейсами позже. Обратите внимание, что вы не можете создать экземпляр абстрактного класса, вы ДОЛЖНЫ его сначала расширить.
(Ключевое слово «protected» означает, что только расширенные классы могут получить доступ к этим методам и переменным.)
Spyro
источник
Интерфейс - это контракт между двумя сторонами, который является инвариантным, высеченным в камне и, следовательно, окончательным. См. Дизайн по контракту .
источник
Интерфейс: Служба системных требований.
В интерфейсе переменные по умолчанию присваиваются модификатором public, static, final access. Так как :
public: иногда случается, что интерфейс может быть помещен в какой-то другой пакет. Таким образом, необходимо получить доступ к переменной из любого места в проекте.
статический: как таковой неполный класс не может создать объект. Таким образом, в проекте нам нужно получить доступ к переменной без объекта, чтобы мы могли получить доступ с помощью
interface_filename.variable_name
final: предположим, что один интерфейс реализуется многими классами, и все классы пытаются получить доступ и обновить переменную интерфейса. Так что это приводит к непоследовательности изменения данных и влияет на любой другой класс. Так что нужно объявить модификатор доступа с помощью final.
источник
В
Java
интерфейс не позволяет объявлять переменные экземпляра. Использование переменной, объявленной в интерфейсе в качестве переменной экземпляра, вернет ошибку времени компиляции.Вы можете объявить постоянную переменную, использование
static final
которой отличается от переменной экземпляра.источник
Интерфейс может быть реализован любыми классами, и что, если это значение было изменено одним из реализующих его классов, тогда будут введены в заблуждение другие реализующие классы. Интерфейс в основном является ссылкой для объединения двух связанных, но разных сущностей. Поэтому по этой причине объявленная переменная внутри интерфейса будет неявно конечной, а также статической, поскольку интерфейс не может быть создан.
источник
Подумайте о веб-приложении, в котором у вас есть определенный интерфейс, а другие классы реализуют его. Поскольку вы не можете создать экземпляр интерфейса для доступа к переменным, вам нужно иметь статическое ключевое слово. Поскольку оно статическое, любое изменение значения будет отражаться для других экземпляров, которые его реализовали. Поэтому, чтобы предотвратить это, мы определяем их как окончательные.
источник
Только что попробовал в Eclipse, переменная в интерфейсе по умолчанию является окончательной, поэтому вы не можете ее изменить. По сравнению с родительским классом переменные однозначно изменяемы. Зачем? С моей точки зрения, переменная в классе - это атрибут, который будет наследоваться детьми, и дети могут изменять его в соответствии с их реальной потребностью. Напротив, интерфейс определяет только поведение, а не атрибут. Единственная причина для добавления переменных в интерфейс - это использовать их как константы, связанные с этим интерфейсом. Тем не менее, это не очень хорошая практика, согласно следующей выдержке:
«Размещение констант в интерфейсе было популярной техникой в первые дни Java, но теперь многие считают это отвратительным использованием интерфейсов, поскольку интерфейсы должны иметь дело со службами, предоставляемыми объектом, а не его данными. Кроме того, используемые константы классом обычно являются детали реализации, но размещение их в интерфейсе продвигает их к общедоступному API класса ".
Я тоже пробовал либо ставить статичную, либо не делать разницы вообще. Код как ниже:
источник