Должны ли методы в интерфейсе Java быть объявлены с модификатором открытого доступа или без него? - PullRequest
274 голосов
/ 02 октября 2008

Должны ли методы в интерфейсе Java быть объявлены с модификатором доступа public или без него?

Технически это не имеет значения, конечно. Метод класса, который реализует interface, всегда равен public. Но что является лучшим соглашением?

Сама Java не соответствует этому. См., Например, Collection против Comparable или Future против ScriptEngine.

Ответы [ 12 ]

321 голосов
/ 02 октября 2008

JLS проясняет это:

Разрешено, но не рекомендуется в качестве стиля, избыточно указывать модификатор public и / или abstract для метода, объявленного в интерфейсе.

41 голосов
/ 02 октября 2008

Модификатор public должен быть опущен в интерфейсах Java (по моему мнению).

Поскольку он не добавляет никакой дополнительной информации, он просто отвлекает внимание от важных вещей.

Большинство руководств по стилю рекомендуют не указывать это, но, конечно, самое важное - это согласованность по всей кодовой базе, особенно для каждого интерфейса. Следующий пример может легко запутать кого-то, кто не владеет Java на 100%:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
8 голосов
/ 06 марта 2016

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

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

Во-вторых, хотя можно инициировать объекты типа интерфейса, но интерфейс реализуется классами, которые его реализуют, а не наследуются. И поскольку интерфейс может быть реализован (реализован) различными несвязанными классами, которые не находятся в одном пакете, модификатор защищенного доступа также недопустим. Так что для модификатора доступа у нас есть только публичный выбор.

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

В-четвертых, Интерфейс может включать только константу в качестве своих элементов данных, что означает, что они должны быть конечными и, конечно, конечные константы объявляются как статические, чтобы сохранить только один их экземпляр. Поэтому static final также является обязательным для констант интерфейса.

Таким образом, в заключение, хотя использование абстрактных методов public и public static final перед константами интерфейса допустимо, но, поскольку нет других опций, оно считается избыточным и не используется.

6 голосов
/ 02 июля 2017

С введением модификаторов private, static, default для методов интерфейса в Java 8/9 все становится более сложным, и я склонен считать, что полные объявления более читабельны (для компиляции требуется Java 9) :

public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}
5 голосов
/ 02 октября 2008

Я использовал методы объявления с модификатором public, потому что он делает код более читабельным, особенно с подсветкой синтаксиса. В нашем последнем проекте мы использовали Checkstyle, который показывает предупреждение с конфигурацией по умолчанию для public модификаторов в интерфейсных методах, поэтому я переключился на их пропуск.

Так что я не совсем уверен, что лучше, но мне действительно не нравится использовать public abstract в интерфейсных методах. Eclipse делает это иногда при рефакторинге с помощью «Extract Interface».

5 голосов
/ 02 октября 2008

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

Худшее, что я видел, - это интерфейс с объявленными методами abstract ...

4 голосов
/ 02 октября 2008

Я всегда пишу то, что использовал бы, если бы не было интерфейса, и я писал прямую реализацию, то есть я бы использовал public.

3 голосов
/ 10 августа 2010

Я предпочитаю пропустить это, я где-то читал, что интерфейсы по умолчанию public и abstract.

К моему удивлению, книга - Head First Design Patterns , использует public с объявлением интерфейса и методами интерфейса ..., что заставило меня переосмыслить еще раз, и я попал на этот пост.

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

2 голосов
/ 13 февраля 2019

Я не согласен с популярным ответом, что публичность подразумевает, что есть другие варианты, и поэтому их не должно быть. Дело в том, что теперь с Java 9 и за его пределами есть другие варианты.

Я думаю, что вместо этого Java должен обеспечивать / требовать указания 'public'. Зачем? Поскольку отсутствие модификатора означает «пакетный» доступ везде, а наличие этого в качестве особого случая приводит к путанице. Если бы вы просто сделали это ошибкой компиляции с четким сообщением (например, «Доступ к пакету не разрешен в интерфейсе».), Мы избавились бы от очевидной двусмысленности, которую представляет возможность пропустить public.

Обратите внимание на текущую формулировку: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Метод в теле интерфейса может быть объявлен public или частный (§6.6). Если модификатор доступа не указан, метод неявно общедоступен. Это разрешено, но не рекомендуется как стиль, чтобы избыточно указать публичный модификатор для метода объявление в интерфейсе. "

Видите, что «личное» разрешено. Я думаю, что последнее предложение должно было быть удалено из JLS. К сожалению, «неявно публичное» поведение когда-либо было разрешено, поскольку теперь оно, вероятно, останется для обратной совместимости и приведет к путанице, что отсутствие модификатора доступа означает «открытый» в интерфейсах и «пакет» в других местах.

2 голосов
/ 31 июля 2013

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

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

Добавление этих модификаторов в ваш код является излишним и бесполезным и может привести только к выводу, что вам не хватает знаний и / или понимания основ Java.

...