Почему некоторые разработчики объявляют объекты String в своих интерфейсах на Java и как они работают?

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

public interface SampleInterface {
    String EXAMPLE_ONE = "exampleOne";
    String USER_ID     = "userId";

    public void setValue();
}

Если какой-либо класс реализует этот интерфейс SampleInterface, что происходит с переменными, которые он объявляет?

  • Получает ли унаследованный класс доступ ко всем переменным?
  • Требуется ли переопределить декларируемые классы?
  • Что может быть целью объявления переменных String в интерфейсе, когда мы могли бы использовать абстрактный класс для этой цели?

Кроме того, что является лучшей стратегией:

  • Класс с конечными статическими полями и частным конструктором?
  • Интерфейс с переменными, как показано выше?

Ответы

Ответ 1

Это общая идиома Java

В интерфейсе Java все члены неявно public, а поля, в частности, неявно public static final. У вас нет выбора. Если вы попытаетесь использовать любой другой уровень разрешений, отличный от public, компилятор будет кричать на вас, поскольку это не имеет никакого смысла.

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

Почему люди используют эту идиому?

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

Таким образом, вы можете вызвать как usuall MyInterface.MY_CONST для доступа к одной из ваших констант.

Вы делали бы это по интерфейсу обычно, когда вам не нужно определять какое-либо поведение, поэтому, когда вам не нужны какие-либо методы. Это действительно просто статический магазин (часто сам интерфейс также создается как final). Вы можете использовать abstract class для этого, например, если вы хотите инкапсулировать и скрыть детали реализации. Но в этом случае, когда у вас есть как поля, так и методы, обычно ваша цель - просто предоставить некоторые константы и контракт для подклассов.

Учитывая в вашем случае также подпись метода как часть вашего интерфейса, очевидно, намерение реализовать этот интерфейс. В этом случае вы также можете получить доступ к своим данным:

  • MyInterface.MY_CONST,
  • или MyExtendingClass.MY_CONST,
  • или instanceOfMyExtendingClass.MY_CONST.

Дополнительная информация

Для получения дополнительной информации см.:

  • этот элемент часто задаваемых вопросов и те, которые следуют за ним,
  • комментарии Анона и Джеффа относительно злоупотреблений этой формы,
  • Тип перечисления, введенный с Java 5 (который, и, как упоминал Джон, во многих случаях определенно будет лучшей идеей: более элегантный, с дополнительным преимуществом безопасности типов при его передаче и использованием довольно оптимизированных конструкций для поиска и управления значениями).