Почему некоторые разработчики объявляют объекты String в своих интерфейсах на Java и как это работает? - PullRequest
13 голосов
/ 14 декабря 2010

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

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

    public void setValue();
}

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

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

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

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

1 Ответ

29 голосов
/ 14 декабря 2010

Это идиома Java

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

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

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

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

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

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

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

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

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

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

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