С какой целью вы можете объявлять константы в интерфейсе Java?
В спецификации указано, что интерфейс предназначен для определения контракта для того, что класс может выполнять, и содержит набор методов, необходимых для реализации. Но в то же время интерфейс может иметь константы.
С какой целью это разрешено в Java?
В чем смысл существования констант в интерфейсе и как их можно использовать в нем? Насколько я понимаю, их можно воспринимать только как аргументы методами. Но я не вижу большого смысла, потому что интерфейс ничего не говорит о , как класс будет реализовывать свои методы.
Ответы
Ответ 1
Постоянная часть также является частью интерфейса. Константные значения используются в дизайне, чтобы избежать Магических чисел, то есть чисел, которые имеют определенный смысл для реализации, но, похоже, выходят из ниоткуда.
Есть много случаев, когда числовые значения влияют на поведение кода. Рассмотрим, например, интерфейс для кнопки GUI. Как эта кнопка фактически нарисована до реализации; но какая кнопка является частью контракта, который формирует интерфейс: является ли это обычной кнопкой, имеет ли она изображение или это флажок? Это поведение может быть изменено с использованием констант, обычно используемых значениями OR'ing: Например, int buttonType = PUSHBUTTON|IMAGEBUTTON
.
Ответ 2
Константы могут использоваться вне интерфейса.
Например, они могут использоваться классами, реализующими интерфейс. Это может быть полезно, если для всех классов реализации требуется одно определение.
Например, рассмотрим интерфейс, который определяет некоторые константы стиля побитового ИЛИ, которые могут использоваться последовательно во всех подклассах. Требуется только одно определение, и нужно изучить только один набор.
Ответ 3
Представьте приложение, которое использует такие ресурсы, как изображения или звуки. Вы можете определить общий интерфейс для своих ресурсов.
interface MyResource {
void load();
void dispose();
// ...
}
Структура вашей папки может выглядеть следующим образом:
+ Root
|--+ Resources
|--+ Images
|--+ Sounds
|--+ Data
Вы знаете, что все ваши ресурсы будут находиться под Root/Resources/
.
Эта информация может быть разделена и известна не только вашими ресурсами, но и другими вашими компонентами приложения.
Имея это в виду, теперь ваш интерфейс становится следующим:
interface MyResource {
public static final String RESOURCE_ROOT_PATH = "Root/Resources/";
void load();
void dispose();
// ...
}
Ваши конкретные реализации, такие как изображение, могут определять собственный корневой путь на основе общего пути для всех ресурсов.
class MyImage implements MyResource {
public static final String IMAGE_ROOT_PATH =
MyResource.RESOURCE_ROOT_PATH + "Images/";
...
}
В качестве альтернативы вы можете посмотреть такие интерфейсы, как javax.swing.SwingConstants
, которые используются для совместного использования констант для определенной функциональности среди реализаций.
Но, опять же, для такого рода вещей я бы предпочел использовать enum
, в настоящее время.
Ответ 4
Давайте объясним с примером:
public interface People {
/**
* Gets the population for the given type
*/
public Population getPopulationForType(int populationType);
}
Вы находите, что вышеуказанный контракт легко понять? Или лучше не будет следующего?
public interface People {
int BLACK_POPULATION_TYPE = 0;
int ASIAN_POPULATION_TYPE = 1;
int WHITE_POPULATION_TYPE = 2;
/**
* Gets the population for the given type
*/
public Population getPopulationForType(int populationType);
}
У вас может быть реализация FrenchPeople, AmericanPeople и ChinesePeople, но все они должны возвращать населенность для всех трех возможных типов людей.
Ответ 5
Одно из применений таких констант для меня post-Java 5 (которое принесло enum
, которые превосходят битмаскировку и могут быть объявлены и на интерфейсах) - это когда константа является частью контракта метода.
Рассмотрим такой интерфейс:
public interface Element {
Element NONE = new EmptyElement();
/**
* Looks up an element using this element as a root.
* If the lookup fails, returns Element.NONE.
*/
Element findElements(String searchBy);
}
Константа является частью контракта метода и должна, я полагаю, быть в интерфейсе. Это полезно в программировании API, поскольку вы можете предлагать стандартные или специальные значения возврата для методов API для всех, кто их использует и проверяет.
Наиболее распространенный случай этого предотвращает проблемы с неоднозначными возвращаемыми значениями null
(например, метод HashMap#get()
возвращает null
как для отсутствующего ключа, так и для значения null
), но есть намного больше к нему, чем просто nulls - любые специальные значения, которые могут быть возвращены, должны быть, я думаю, на интерфейсе.
Ответ 6
Одно возможное использование интерфейсных констант - убедиться, что константы видны во всех классах реализации. Конечно, вы можете поместить все в класс и использовать один класс в этих классах реализации, но гораздо проще определить константы на уровне спецификации.
Подумайте об этом так; даже если константы не определяют "реализацию", они присутствуют там, где им нужна какая-либо реализация.
Ответ 7
Их можно использовать, чтобы дать символический смысл возвращаемым аргументам args/input методов. Это было так предродовым дням.