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

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

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

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


person Benno Richters    schedule 02.10.2008    source источник
comment
Это плохо, потому что если написать его как общедоступное, это означает, что он может быть закрытым.   -  person Pacerier    schedule 19.11.2011
comment
Вам следует избегать избыточного синтаксиса любой формы.   -  person user207421    schedule 21.08.2013
comment
@Pacerier, хотя я согласен с тем, что использовать public в этом контексте плохо, методы интерфейса по умолчанию могут теперь (с java 9) быть частными. Предлагаю вам удалить свой комментарий, так как он устарел.   -  person aioobe    schedule 02.08.2016
comment
Да, в Java 9 могут быть внесены изменения. Написание его как общедоступного подразумевает, что он может быть закрытым. Поскольку именно это кажется возможным в Java 9, этот аргумент теперь имеет преимущество в виде записи public.   -  person MC Emperor    schedule 27.07.2017


Ответы (12)


JLS дает понять это :

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

person Jon Skeet    schedule 02.10.2008
comment
Ссылка JLS выше была для Java 7 в то время, когда я ее читал. После комментариев о том, что Java 9 допускает использование закрытых методов, я просто хотел подтвердить, что очень похожая формулировка все еще существует для SE9 JLS. (public часть такая же, and/or abstract часть удалена) - person OzgurH; 20.02.2018
comment
По-прежнему актуально в SE11 JLS - person Ortomala Lokni; 02.11.2018
comment
Обновление: Java 13 docs.oracle. com / javase / specs / jls / se13 / html / jls-9.html # jls-9.4. - person Do Nhu Vy; 31.01.2020

Модификатор public не следует использовать в интерфейсах Java (на мой взгляд).

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

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

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
person Rasmus Faber    schedule 02.10.2008
comment
У вас есть ссылка на такое руководство по стилю? - person Benno Richters; 02.10.2008
comment
Последовательность - это, безусловно, самая важная вещь и ответ на 99% вопросов такого типа. - person SCdF; 02.10.2008
comment
Согласовано повторно: последовательность. Что-то для ваших документов стандартов кодирования, ребята :) - person JeeBee; 02.10.2008
comment
Bno: Один пример - это спецификация языка Java, другой - Checkstyle. - person Rasmus Faber; 02.10.2008

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

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

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

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

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

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

person Leo The Four    schedule 06.03.2016

С введением модификаторов 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() {}

}
person Werner Thumann    schedule 02.07.2017

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

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

person PhiLho    schedule 02.10.2008

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

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

person cretzel    schedule 02.10.2008
comment
Но только если вы установите два флажка, объявляйте методы как общедоступные, абстрактные. - person MetroidFan2002; 02.10.2008

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

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

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

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

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

person swpalmer    schedule 13.02.2019

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

person JeeBee    schedule 02.10.2008
comment
Не могли бы вы также явно объявить все методы интерфейса абстрактными? - person Dan Dyer; 02.10.2008
comment
Это интерфейс, а не абстрактный класс. Что касается «общедоступного», это 7 символов, которые вы набираете, когда думаете об этом, большое дело! И это то, как это будет определено в реализации: +1 для согласованности, уравновешивая -1 для избыточности. - person JeeBee; 02.10.2008

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

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

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

person Pradeep Sharma    schedule 10.08.2010
comment
Чтобы уточнить, если вы опустите модификатор доступа public в объявлении интерфейса, он будет не общедоступным и абстрактным по умолчанию. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef. html - person Jabbslad; 20.01.2014

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

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

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

person Iuliana Cosmina    schedule 31.07.2013
comment
Но вы также можете реализовать абстрактные методы с защищенным доступом - в абстрактном классе. Так что публичность не обязательна. Добавление чего-то явного, аналогичного тому, что было бы по умолчанию, всегда избыточно, но не всегда бесполезно. - person swpalmer; 03.05.2019
comment
Но вопрос в интерфейсах. Я не хотел отвлекаться. Я имею в виду, что начиная с Java 8 мы можем также говорить о частных методах и методах по умолчанию в интерфейсах, верно? Так что это обсуждение может быть довольно длинным, если мы захотим. ;) - person Iuliana Cosmina; 29.05.2019

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

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

person serg10    schedule 02.10.2008

Люди будут изучать ваш интерфейс на основе автозавершения кода в своей среде IDE или в Javadoc, а не при чтении исходного кода. Так что нет смысла указывать в источнике слово «общедоступно» - никто его не читает.

person Tim Boudreau    schedule 31.03.2012
comment
Я действительно должен не согласиться с утверждением, что никто не читает источник. Я думаю, что многие люди используют, например, F3 в Eclipse, чтобы увеличить масштаб кода. Такие инструменты, как Maven, не зря предлагают возможность загрузки исходников, а не только JavaDoc. - person Benno Richters; 16.04.2012
comment
Это не точная причина того, чтобы не добавлять модификатор доступа public к интерфейсу. Это сделано по замыслу и после тщательного обдумывания. - person mtk; 21.06.2012