Почему все поля в интерфейсе неявно статичны и конечны?
Я просто пытаюсь понять, почему все поля, определенные в интерфейсе неявно static
и final
. Идея сохранения полей static
имеет смысл для меня, как вы не можете иметь объекты интерфейса, но почему они final
(неявно)?
любой знает, почему дизайнеры Java пошли с созданием полей в интерфейсе static
и final
?
7 ответов:
интерфейс не может иметь поведение или состояние, потому что он предназначен для указания только контракта взаимодействия, без деталей реализации. Никакое поведение не принудительно, не разрешая тела метода / конструктора или статические / экземплярные инициализирующие блоки. Никакое состояние не применяется, разрешая только статические конечные поля.Поэтому класс может иметь состояние (статическое состояние), но состояние экземпляра не выводится интерфейсом.
BTW: константа в Java определяется статическим конечным полем (и по соглашению имя использует UPPER_CASE_AND_UNDERSCORES).
ПРИЧИНА БЫТЬ
final
любые реализации могут изменить значение полей, если они не определены как окончательные. Тогда они станут частью реализации. Интерфейс-это чистая спецификация без какой-либо реализации.
ПРИЧИНА БЫТЬ
static
если они статичны, то они принадлежат интерфейсу, а не объекту, ни типу времени выполнения объекта.
здесь есть несколько моментов, которые замалчиваются:
только потому, что поля в интерфейсе неявно статичны final, не означает, что они должны быть константами времени компиляции или даже неизменяемыми. Вы можете определить, например,
interface I { String TOKEN = SomeOtherClass.heavyComputation(); JButton BAD_IDEA = new JButton("hello"); }
(помните, что делать это внутри определения аннотации смущает, что javac, связанные с тем, что выше фактически компилируется в статический инициализатор.)
кроме того, причина этого ограничение скорее стилистическое, чем техническое, и многие люди будут хотелось бы видеть его расслабленным.
поля должны быть статическими, потому что они не могут быть абстрактными (например, методов). Поскольку они не могут быть абстрактными, разработчики не смогут логически обеспечить различную реализацию полей.
поля должны быть окончательными, я думаю, потому что поля могут быть доступны для многих различных исполнителей позволяет им быть изменяемыми может быть проблематичным (как синхронизация). Также, чтобы избежать его повторной реализации (скрытой).
просто мои мысли.
Я считаю, что требование о том, чтобы поля были окончательными, является чрезмерно ограничительным и ошибкой разработчиков языка Java. Бывают случаи, например обработка дерева, когда вам нужно установить константы в реализации, которые необходимы для выполнения операций над объектом типа интерфейса. Выбор пути кода в реализующем классе - это kludge. Обходной путь, который я использую, чтобы определить функцию интерфейса и реализовать ее, возвращая литерал:
public interface iMine { String __ImplementationConstant(); ... } public class AClass implements iMine { public String __ImplementationConstant(){ return "AClass value for the Implementation Constant"; } ... } public class BClass implements iMine { public String __ImplementationConstant(){ return "BClass value for the Implementation Constant"; } ... }
однако, было бы проще, яснее и менее склонны к аберрантной реализации использовать этот синтаксис:
public interface iMine { String __ImplementationConstant; ... } public class AClass implements iMine { public static String __ImplementationConstant = "AClass value for the Implementation Constant"; ... } public class BClass implements iMine { public static String __ImplementationConstant = "BClass value for the Implementation Constant"; ... }
спецификация, контракты... Машинная инструкция для доступа к полю использует адрес объекта плюс смещение поля. Так как классы могут реализовать много интерфейсов, нет никакого способа сделать неокончательное поле интерфейса, чтобы иметь то же самое смещение во всех классах, которые расширяют этот интерфейс. Поэтому должен быть реализован другой механизм доступа к полю: два доступа к памяти (get Field offset, get field value) вместо одного плюс ведение вида таблицы виртуальных полей (аналог таблицы виртуальных методов). Думаю, они просто не хотели усложнять jvm для функциональности, которую можно легко смоделировать с помощью существующих материалов (методов).
в scala мы можем иметь поля в интерфейсах, хотя внутренне они реализованы, как я объяснил выше (как методы).
static
:что-нибудь (переменная или метод), что составляет
static
в Java можно вызвать какClassname.variablename
илиClassname.methodname
или напрямую. Не обязательно вызывать его только с помощью имени объекта.в интерфейсе объекты не могут быть объявлены и
static
позволяет вызывать переменные только через имя класса без необходимости имени объекта.
final
:это помогает поддерживать постоянное значение для переменная, поскольку она не может быть переопределена в своих подклассах.