Почему переменные интерфейса статические и окончательные по умолчанию в Java?
Почему по умолчанию переменные интерфейса статичны и окончательны?
Ответ 1
Из часто задаваемых вопросов о дизайне интерфейса Java от Philip Shaw:
Интерфейсные переменные являются статическими, поскольку интерфейсы Java не могут быть созданы сами по себе; значение переменной должно быть назначено в статическом контексте, в котором не существует экземпляра. Окончательный модификатор гарантирует, что значение, присвоенное переменной интерфейса, является истинной константой, которая не может быть повторно назначена программным кодом.
Ответ 2
Поскольку интерфейс не имеет прямого объекта, единственный способ доступа к ним - использовать класс/интерфейс и, следовательно, поэтому, если переменная интерфейса существует, она должна быть статической, иначе она не будет вообще доступна для внешнего мира, Теперь, поскольку он является статическим, он может содержать только одно значение, и любые его классы, которые его реализуют, могут изменить его, и, следовательно, все будет бесполезно.
Следовательно, если вообще есть интерфейсная переменная, она будет неявно статичной, окончательной и, очевидно, публичной!!!
Ответ 3
public: для доступности для всех классов, как и методы, присутствующие в интерфейсе
static: поскольку интерфейс не может иметь объект, имя интерфейсаName.variableName может использоваться для ссылки на него или непосредственно переменное имя в классе, реализующем его.
final: сделать их константами. Если 2 класса реализуют один и тот же интерфейс, и вы даете им право изменять значение, конфликт будет возникать в текущем значении var, поэтому разрешается только однократная инициализация.
Также все эти модификаторы неявны для интерфейса, вам действительно не нужно указывать какие-либо из них.
Ответ 4
(Это не философский ответ, а более практический). Требование для модификатора 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
(в тот же поток или иначе), что в этом случае может быть катастрофическим (семантически это).
Так как мы не знаем, как каждая реализация interface
будет использовать эти переменные, они должны неявно быть final
.
Ответ 5
Поскольку все остальное является частью реализации, а интерфейсы не могут содержать никакой реализации.
Ответ 6
static - потому что интерфейс не может иметь никакого экземпляра. и final - потому что нам не нужно его менять.
Ответ 7
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
Я думаю, что это единственная причина, по которой переменная интерфейса статична.
Не объявлять переменные внутри интерфейса.
Ответ 8
потому что:
Static
: поскольку у нас не может быть объектов интерфейсов, нам следует избегать использования переменных-членов уровня объекта и использовать переменные уровня класса, то есть статические.
Final
: чтобы у нас не было неоднозначных значений для переменных (проблема Алмаза - множественное наследование).
И согласно интерфейсу документации это контракт, а не реализация.
ссылка: Абхишек Джайн ответ на квору
Ответ 9
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
}
Вы также можете использовать абстрактный класс без какого-либо интерфейса, если вы УВЕРЕНЫ, что вы не хотите его реализовывать вместе с другими интерфейсами позже. Обратите внимание, что вы не можете создать экземпляр абстрактного класса, который вы ДОЛЖНЫ расширить его сначала.
(Ключевое слово "protected" означает, что доступ к этим методам и переменным могут получить только расширенные классы.)
Spyro
Ответ 10
Интерфейс - это контракт между двумя сторонами, которые являются инвариантными, вырезанными в камне, следовательно, окончательными. См. "Дизайн по контракту" .
Ответ 11
В Java
интерфейс не позволяет вам объявлять какие-либо переменные экземпляра. Использование переменной, объявленной в интерфейсе как переменной экземпляра, вернет ошибку времени компиляции.
Вы можете объявить постоянную переменную, используя static final
, которая отличается от переменной экземпляра.
Ответ 12
Интерфейс может быть реализован любыми классами, и что, если это значение изменилось одним из тех, кто реализует класс, тогда будет введено в заблуждение для других классов реализации. Интерфейс - это, в основном, ссылка на объединение двух параллельных, но разных сущностей. Таким образом, декларирующая переменная внутри интерфейса будет неявно окончательной, а также статической, поскольку интерфейс не может быть создан.
Ответ 13
Подумайте о веб-приложении, где вы определили интерфейс, а другие классы его реализуют. Поскольку вы не можете создать экземпляр интерфейса для доступа к переменным, вам нужно иметь статическое ключевое слово. Поскольку его статическое любое изменение значения будет отражать другие экземпляры, которые его внедрили. Поэтому, чтобы предотвратить это, мы определяем их как окончательные.
Ответ 14
Просто попробованный в 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));
}
}
Ответ 15
Я думаю, потому что интерфейсы не могут быть созданы, поэтому все переменные объявлены как static
.
Использование ключевого слова final
означает, что у него нет тела.