Почему переменные интерфейса статические и конечные по умолчанию в Java?Почему переменные интерфейса статичны и окончательны по умолчанию?
ответ
От Java дизайн интерфейса FAQ Филипа Шоу:
Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
Обратите внимание, что абстрактные классы не могут быть созданы «сами по себе», и они могут иметь переменные экземпляра. – macias
Если мы попытались изменить значение переменной в классе реализации, мы столкнемся с приведенной ниже ошибкой. Исключение из потока «main» java.lang.Error: Неразрешенная проблема компиляции: \t Окончательное поле Interface1.name не может быть назначено – srinivas
Это объяснение модификатора 'static' полностью ложно. Переменные публичного экземпляра класса являются частью его интерфейса, и нет никаких причин, по которым они не должны быть абстрагированы в Java-интерфейсе, как методы экземпляра. Не имеет значения, что Java-интерфейс не может быть создан напрямую - у вас все еще могут быть экземпляры классов, которые реализуют «интерфейс», и разумно требовать, чтобы у них была определенная переменная открытого экземпляра. Что касается части «final», это вообще не дает объяснений - это просто описывает, что означает «final». – pyrocrasty
Поскольку все остальное является частью реализации, а интерфейсы не могут содержать никакой реализации.
, тогда в чем причина финала. – Jothi
Чтобы указать, что его константа. Java не имеет ключевого слова const. static final - это то, как вы объявляете константы. –
С Java 8 они могут содержать реализацию, но настоятельно рекомендуется не использовать ее, если вам не нужна совместимость с backwarts. :) – codepleb
статический - потому что интерфейс не может иметь экземпляр. и окончательный - потому что нам не нужно его менять.
«нам не нужно» == «нам не разрешено», не смешивайте значения. – peterh
Я думаю, что это потому, что интерфейсы не могут быть созданы, поэтому все переменные объявлены как static
. Использование ключевого слова final
означает, что у него нет тела.
downvoting, потому что его вводящий в заблуждение. static - потому что интерфейс не может иметь никакого экземпляра. и окончательный - потому что нам не нужно его менять. – uneakharsh
varaibles объявлен статическим, поскольку интерфейс не может быть создан и доступен только для доступа к переменным, делая их статическими. Конечное ключевое слово используется, чтобы сделать эти переменные постоянными, чтобы они не могли быть изменены. –
Поскольку интерфейс не имеет прямого объекта, единственным способом доступа к ним является использование класса/интерфейса и, следовательно, поэтому, если переменная интерфейса существует, она должна быть статической, иначе она вообще не будет доступна для внешнего Мир. Теперь, поскольку он является статическим, он может содержать только одно значение, и любые классы, которые его реализуют, могут изменить его, и, следовательно, все будет бесполезно.
Следовательно, если вообще есть переменная интерфейса, она будет неявно статичной, окончательной и, очевидно, открытой !!!
Конечно, переменная экземпляра была бы доступна, если бы она была разрешена в Java 'interface'. Класс реализует интерфейс, объявляя переменную экземпляра (в соответствии с требованиями интерфейса). Его конструктор (или другой метод) задает переменную экземпляра. Когда экземпляр класса создается, вы сможете получить доступ к его переменной экземпляра. – pyrocrasty
Java позволяет статическим методам с телами существовать в интерфейсе. Они могут получить доступ к статическим переменным. Они просто не могут их изменить, что означает, что статические функции не могут хранить какие-либо данные. – simpleuser
Java не допускает описания абстрактных переменных и/или конструкторов в интерфейсах. Решение: Просто повесьте абстрактный класс между интерфейсом и вашей реализацией, который простирается только абстрактный класс, как так:
public interface IMyClass {
void methodA();
String methodB();
Integer methodC();
}
public abstract class myAbstractClass implements IMyClass {
protected String 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 class
protected void methodA() {
//Do something
}
//Add additional methods here which must be implemented in the concrete class
protected abstract Long methodD();
//Write some completely new methods which can be used by all subclasses
protected Float methodE() {
return 42.0;
}
}
public class 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
}
Вы также можете использовать абстрактный класс без любого интерфейса, если вы уверены, что вы не делаете захотите реализовать его вместе с другими интерфейсами позже. Обратите внимание, что вы не можете создать экземпляр абстрактного класса, который вы ДОЛЖНЫ расширить его в первую очередь.
(«защищенных» ключевое слово означает, что только расширенные классы могут получить доступ к этим методам и переменным.)
Spyro
В Java
, интерфейс не позволяет объявлять переменные экземпляра. Использование переменной, объявленной в интерфейсе как переменной экземпляра, вернет ошибку времени компиляции.
Вы можете объявить постоянную переменную, используя static final
, которая отличается от переменной экземпляра.
Интерфейс может быть реализован любыми классами, и что, если это значение было изменено одним из них, реализующим класс, тогда будет введено в заблуждение для других классов реализации. Интерфейс - это, в основном, ссылка на объединение двух параллельных, но разных сущностей. Таким образом, декларирующая переменная внутри интерфейса будет неявно окончательной, а также статической, поскольку интерфейс не может быть создан.
Подумайте о веб-приложении, где у вас есть определенный интерфейс и другие его классы. Поскольку вы не можете создать экземпляр интерфейса для доступа к переменным, вам нужно иметь статическое ключевое слово. Поскольку его статическое любое изменение значения будет отражать другие экземпляры, которые его внедрили. Поэтому, чтобы предотвратить это, мы определяем их как окончательные.
Интерфейс - это контракт между двумя сторонами, который является инвариантным, вырезанным в камне, следовательно, окончательным. См. Design by Contract.
public interface A{
int x=65;
}
public interface B{
int x=66;
}
public class D implements A,B {
public static void main(String[] a){
System.out.println(x); // which x?
}
}
Вот решение.
System.out.println(A.x); // done
Я думаю, что это единственная причина, по которой переменная интерфейса является статической.
Не объявляйте переменные внутри интерфейса.
На самом деле без спецификации «Ax» она даже не будет компилироваться », поэтому на самом деле безопасно использовать переменные (которые неявно являются публичными статическими окончательными) в интерфейсах – Marco
Я не согласен с ответом, поскольку @Marco сказал, что он даже не будет компилироваться. Пока я не нашел другого недостатка, может быть, просто, что вы не видите написанного 'static final' перед переменной, которая на самом деле является статической и окончательный. – Micer
общественный: для доступности во всех классах, так же, как методы, присутствующих в интерфейсе
статического: как интерфейс не может иметь объект, то interfaceName.variableName может использоваться для ссылки на него или непосредственно переменное имя в классе, реализующем его.
final: сделать их константами. Если 2 класса реализуют один и тот же интерфейс, и вы даете им право изменять значение, конфликт будет возникать в текущем значении var, поэтому разрешается только однократная инициализация.
Также все эти модификаторы неявны для интерфейса, вам действительно не нужно указывать какие-либо из них.
(Это не философский ответ, а более практичный). Требование для модификатора static
очевидно, на что ответили другие. В принципе, поскольку интерфейсы не могут быть созданы, единственный способ получить доступ к своим полям - сделать их полем класса - static
.
Причина, по которой interface
автоматически становится final
(константа), заключается в том, чтобы предотвратить различные варианты реализации, случайно изменяя значение переменной интерфейса, которое может непреднамеренно повлиять на поведение других реализаций. Представьте себе сценарий ниже, где interface
свойство явно не стало final
на Java:
public interface Actionable {
public static boolean isActionable = false;
public void performAction();
}
public NuclearAction implements Actionable {
public void performAction() {
// Code that depends on isActionable variable
if (isActionable) {
// Launch nuclear weapon!!!
}
}
}
Теперь, просто подумайте, что произойдет, если другой класс, который реализует Actionable
изменяет состояние переменного интерфейса:
public CleanAction implements Actionable {
public void performAction() {
// Code that can alter isActionable state since it is not constant
isActionable = true;
}
}
Если эти классы загружаются в один JVM загрузчиком классов, тогда поведение NuclearAction
может быть затронуто другим классом CleanAction
, когда его performAction()
вызывается после выполнения CleanAction
(в t он тот же поток или иначе), что в этом случае может быть катастрофическим (семантически то есть).
Поскольку мы не знаем, как каждая реализация interface
будет использовать эти переменные, они должны неявно быть final
.
Просто попробованный в Eclipse, переменная в интерфейсе по умолчанию является окончательной, поэтому вы не можете ее изменить. По сравнению с родительским классом переменные определенно изменяемы. Зачем? С моей точки зрения, переменная в классе является атрибутом, который будет унаследован детьми, а дети могут изменить его в соответствии с их реальной потребностью.Напротив, интерфейс определяет поведение, а не атрибут. Единственная причина, положенная в переменные в интерфейсе, - использовать их как константы, связанные с этим интерфейсом. Хотя это не является хорошей практикой согласно следующей выдержке:
«Размещение констант в интерфейсе было популярным методом в первые дни Java, но теперь многие считают его неприятным использованием интерфейсов, поскольку интерфейсы должны иметь дело с услуги, предоставляемые объектом, а не его данные. Кроме того, константы, используемые классом, как правило, являются деталями реализации, но размещение их в интерфейсе продвигает их в общедоступный API класса ».
Я также попытался либо ставить статику, либо вообще не имеет никакого значения. Код выглядит следующим образом:
public interface Addable {
static int count = 6;
public int add(int i);
}
public class Impl implements Addable {
@Override
public int add(int i) {
return i+count;
}
}
public class Test {
public static void main(String... args) {
Impl impl = new Impl();
System.out.println(impl.add(4));
}
}
- 1. Почему все поля в интерфейсе неявно статичны и окончательны?
- 2. Почему переменные интерфейса неявно статичны в Java?
- 3. Почему параметры метода/конструктора Java не окончательны по умолчанию?
- 4. Почему интерфейсы статичны?
- 5. Почему статические частные переменные в JavaScript статичны?
- 6. Почему переменные интерфейса общедоступны
- 7. Почему члены в статическом классе не статичны по умолчанию
- 8. Почему внутренние классы RowMapper статичны?
- 9. Почему переменные в Java нестабильны по умолчанию?
- 10. Почему методы Array.Sort() и Array.IndexOf() статичны?
- 11. По умолчанию реализация интерфейса
- 12. Почему методы класса Math статичны?
- 13. Почему большинство методов System.Array статичны?
- 14. Почему глобальные и статические переменные инициализируются значениями по умолчанию?
- 15. переменные класса C++ и построение по умолчанию
- 16. переменные интерфейса являются окончательными и статичными по умолчанию, а методы являются общедоступными и абстрактными.
- 17. Python по умолчанию/необязательные переменные
- 18. Member Переменные интерфейса должны быть окончательными ... Почему?
- 19. Переменные Python по умолчанию глобальны?
- 20. Python: переменные, наследование и аргументы по умолчанию
- 21. По умолчанию значение типа интерфейса
- 22. Методы интерфейса Java по умолчанию
- 23. Создание интерфейса DAO по умолчанию
- 24. Почему GoDoc не отображает переменные интерфейса?
- 25. Переменные среды по умолчанию Bitrise
- 26. XmlSerialization - игнорировать переменные по умолчанию
- 27. Переменные экземпляра, по умолчанию атомарные
- 28. gvisMotionChart: изменить переменные по умолчанию
- 29. Почему рекурсивные методы обычно статичны в Java?
- 30. Почему вложенные перечисления неявно статичны в java?
Вы не должны помещать какие-либо переменные внутри интерфейсов. – cherouvim
Поскольку интерфейсы определяют контракты, которые могут быть реализованы различными способами. Значение переменной - это реализация. – cherouvim
Мы, конечно, можем знать, что все классы, реализующие интерфейс, имеют постоянные переменные (например, имена полей). –