Почему переменные интерфейса статические и финальные по умолчанию? - PullRequest
244 голосов
/ 12 марта 2010

Почему переменные интерфейса статические и финальные по умолчанию в Java?

Ответы [ 14 ]

246 голосов
/ 12 марта 2010

Из часто задаваемых вопросов по дизайну интерфейса Java от Филиппа Шоу:

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

источник

36 голосов
/ 04 сентября 2013

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

Следовательно, если вообще есть интерфейсная переменная, она будет неявно статической, конечной и явно общедоступной !!!

33 голосов
/ 03 апреля 2016

public : для доступности для всех классов, как методы, присутствующие в интерфейсе

статический : поскольку интерфейс не может иметь объект, для указания на него можно использовать interfaceName.variableName или непосредственно имя переменной в классе, реализующем его.

final : сделать их постоянными. Если 2 класса реализуют один и тот же интерфейс, и вы предоставляете им обоим право изменять значение, конфликт будет иметь место в текущем значении переменной var, поэтому разрешена только одна временная инициализация.

Также все эти модификаторы неявны для интерфейса, вам не нужно указывать какой-либо из них.

12 голосов
/ 26 июля 2016

( Это не философский ответ, а скорее практический ). Требование к модификатору 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.

9 голосов
/ 12 марта 2010

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

5 голосов
/ 10 марта 2016
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

Я думаю, что это одна из причин, почему переменные интерфейса являются статическими.

Не объявляйте переменные внутри интерфейса.

5 голосов
/ 12 марта 2010

static - потому что интерфейс не может иметь ни одного экземпляраи последнее - потому что нам не нужно его менять.

2 голосов
/ 24 апреля 2018

, потому что:

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

Final: чтобы у нас не было неоднозначных значений для переменных (проблема Алмаза - множественное наследование).

А согласно интерфейсу документации это контракт, а не реализация.

ссылка: ответ Абхишека Джайна на квору http://qr.ae/TU1dTm

2 голосов
/ 15 октября 2013

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

1 голос
/ 18 декабря 2015

Интерфейс - это контракт между двумя сторонами, который является инвариантным, высеченным в камне и, следовательно, окончательным. См. Дизайн по контракту .

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