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

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

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

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

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

Pacerier 19.11.2011 23:01

Вам следует избегать избыточного синтаксиса любой формы.

user207421 21.08.2013 02:32

@Pacerier, хотя я согласен с тем, что использовать public в этом контексте плохо, методы интерфейса по умолчанию может теперь (с java 9) будут частными. Предлагаю вам удалить свой комментарий, так как он устарел.

aioobe 02.08.2016 16:49

Да, в Java 9 могут быть изменения. "Публикация этого сообщения подразумевает, что он может быть закрытым ". Поскольку именно который кажется возможным в Java 9, этот аргумент теперь действительно помогает записать public.

MC Emperor 27.07.2017 15:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
303
4
111 495
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

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

Не могли бы вы также явно объявить все методы интерфейса абстрактными?

Dan Dyer 02.10.2008 15:13

Это интерфейс, а не абстрактный класс. Что касается «общедоступного», это 7 символов, которые вы набираете, когда думаете об этом, большое дело! И это то, как это будет определено в реализации: +1 для согласованности, уравновешивая -1 для избыточности.

JeeBee 02.10.2008 18:51

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

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

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

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}

У вас есть ссылка на такое руководство по стилю?

Benno Richters 02.10.2008 14:25

Последовательность - это, безусловно, самая важная вещь и ответ на 99% вопросов такого типа.

SCdF 02.10.2008 14:27

Согласовано повторно: последовательность. Что-то для ваших документов стандартов кодирования, ребята :)

JeeBee 02.10.2008 14:32

Bno: Один пример - это спецификация языка Java, другой - Checkstyle.

Rasmus Faber 02.10.2008 15:32

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

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

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

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

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

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

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

MetroidFan2002 02.10.2008 17:48
Ответ принят как подходящий

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

It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.

Ссылка JLS выше была для Java 7 в то время, когда я ее читал. После комментариев о том, что Java 9 разрешает закрытые методы, я просто хотел подтвердить, что очень похожая формулировка все еще существует для SE9 JLS. (Часть public такая же, часть and/or abstract была удалена)

OzgurH 20.02.2018 03:02

Все еще верно в SE11 JLS

Ortomala Lokni 02.11.2018 19:12

Обновление: Java 13 docs.oracle.com/javase/specs/jls/se13/html/jls-9.html#jls-9.‌ 4

Do Nhu Vy 31.01.2020 05:12

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

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

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

Чтобы прояснить, если вы опустите модификатор доступа public в объявлении интерфейса, то по умолчанию нет будет общедоступным и абстрактным. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html

Jabbslad 20.01.2014 21:28

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

Я действительно должен не согласиться с утверждением, что никто не читает источник. Я думаю, что многие люди используют, например, F3 в Eclipse, чтобы увеличить масштаб кода. Такие инструменты, как Maven, не зря предлагают возможность загрузки исходников, а не только JavaDoc.

Benno Richters 16.04.2012 12:15

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

mtk 21.06.2012 10:33

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

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

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

Но вы также можете реализовать абстрактные методы с защищенным доступом - в абстрактном классе. Так что публичность не обязательна. Добавление чего-то явного, аналогичного тому, что было бы по умолчанию, всегда избыточно, но не всегда бесполезно.

swpalmer 03.05.2019 20:05

Но вопрос в интерфейсах. Я не хотел отвлекаться. Я имею в виду, что начиная с Java 8 мы можем также говорить о частных методах и методах по умолчанию в интерфейсах, верно? Так что это обсуждение может быть довольно длинным, если мы захотим. ;)

Iuliana Cosmina 29.05.2019 00:25

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

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

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

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

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

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

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

}

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

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

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

"A method in the body of an interface may be declared public or private (§6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of style, to redundantly specify the public modifier for a method declaration in an interface."

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

Другие вопросы по теме