Следует ли объявлять методы в интерфейсе Java с модификатором доступа public или без него?
Технически это, конечно, не имеет значения. Метод класса, реализующий interface, всегда является public. Но что может быть лучше?
Сама Java в этом не последовательна. См., Например, Collection против Comparable или Future против ScriptEngine.
Вам следует избегать избыточного синтаксиса любой формы.
@Pacerier, хотя я согласен с тем, что использовать public в этом контексте плохо, методы интерфейса по умолчанию может теперь (с java 9) будут частными. Предлагаю вам удалить свой комментарий, так как он устарел.
Да, в Java 9 могут быть изменения. "Публикация этого сообщения подразумевает, что он может быть закрытым ". Поскольку именно который кажется возможным в Java 9, этот аргумент теперь действительно помогает записать public.




Я всегда пишу, что бы использовал, если бы не было интерфейса, и я писал прямую реализацию, то есть использовал бы public.
Не могли бы вы также явно объявить все методы интерфейса абстрактными?
Это интерфейс, а не абстрактный класс. Что касается «общедоступного», это 7 символов, которые вы набираете, когда думаете об этом, большое дело! И это то, как это будет определено в реализации: +1 для согласованности, уравновешивая -1 для избыточности.
Модификатор public не следует использовать в интерфейсах Java (на мой взгляд).
Поскольку он не добавляет никакой дополнительной информации, он просто отвлекает внимание от важных вещей.
Большинство руководств по стилю рекомендуют вам не указывать его, но, конечно же, самое важное - обеспечить единообразие всей кодовой базы, особенно для каждого интерфейса. Следующий пример может запутать человека, не владеющего Java на 100%:
public interface Foo{
public void MakeFoo();
void PerformBar();
}
У вас есть ссылка на такое руководство по стилю?
Последовательность - это, безусловно, самая важная вещь и ответ на 99% вопросов такого типа.
Согласовано повторно: последовательность. Что-то для ваших документов стандартов кодирования, ребята :)
Bno: Один пример - это спецификация языка Java, другой - Checkstyle.
Я бы не стал ставить модификаторы, которые применяются по умолчанию. Как уже отмечалось, это может привести к непоследовательности и путанице.
Худшее, что я видел, - это интерфейс с методами, объявленными abstract ...
Это абсолютно субъективно. Я опускаю избыточный модификатор public, поскольку он кажется беспорядком. Как отмечали другие, последовательность - ключ к этому решению.
Интересно отметить, что разработчики языка C# решили усилить это. Объявление метода интерфейса общедоступным в C# на самом деле является ошибкой компиляции. Согласованность, вероятно, не важна для разных языков, поэтому я предполагаю, что это не имеет прямого отношения к Java.
Я использовал методы объявления с модификатором public, потому что он делает код более читабельным, особенно с подсветкой синтаксиса. Однако в нашем последнем проекте мы использовали Checkstyle, который показывает предупреждение с конфигурацией по умолчанию для модификаторов public в методах интерфейса, поэтому я переключился на их исключение.
Так что я не совсем уверен, что лучше, но мне очень не нравится использование public abstract в методах интерфейса. Eclipse иногда делает это при рефакторинге с помощью «Extract Interface».
Но только если вы установите два флажка, объявляйте методы как общедоступные, абстрактные.
JLS проясняет это:
It is permitted, but discouraged as a matter of style, to redundantly specify the
publicand/orabstractmodifier for a method declared in an interface.
Ссылка JLS выше была для Java 7 в то время, когда я ее читал. После комментариев о том, что Java 9 разрешает закрытые методы, я просто хотел подтвердить, что очень похожая формулировка все еще существует для SE9 JLS. (Часть public такая же, часть and/or abstract была удалена)
Все еще верно в SE11 JLS
Обновление: Java 13 docs.oracle.com/javase/specs/jls/se13/html/jls-9.html#jls-9. 4
Я предпочитаю пропускать, где-то читал, что интерфейсы по умолчанию public и abstract.
К моему удивлению, книга - Шаблоны проектирования Head First, использует public с объявлением интерфейса и методами интерфейса ... что заставило меня еще раз переосмыслить, и я попал на этот пост.
В любом случае, я считаю, что избыточную информацию следует игнорировать.
Чтобы прояснить, если вы опустите модификатор доступа public в объявлении интерфейса, то по умолчанию нет будет общедоступным и абстрактным. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Люди будут изучать ваш интерфейс на основе автозавершения кода в своей среде IDE или в Javadoc, а не при чтении исходного кода. Так что нет смысла помещать слово «общедоступно» в источник - никто его не читает.
Я действительно должен не согласиться с утверждением, что никто не читает источник. Я думаю, что многие люди используют, например, F3 в Eclipse, чтобы увеличить масштаб кода. Такие инструменты, как Maven, не зря предлагают возможность загрузки исходников, а не только JavaDoc.
Это не точная причина отказа от добавления модификатора доступа public к интерфейсу. Это сделано по замыслу и после тщательного обдумывания.
Причина того, что методы в интерфейсах по умолчанию являются общедоступными и абстрактными, мне кажется вполне логичной и очевидной.
Метод в интерфейсе по умолчанию является абстрактным, чтобы заставить реализующий класс предоставить реализацию, и по умолчанию является общедоступным, поэтому реализующий класс имеет доступ для этого.
Добавление этих модификаторов в ваш код является избыточным и бесполезным и может привести только к выводу, что вам не хватает знаний и / или понимания основ Java.
Но вы также можете реализовать абстрактные методы с защищенным доступом - в абстрактном классе. Так что публичность не обязательна. Добавление чего-то явного, аналогичного тому, что было бы по умолчанию, всегда избыточно, но не всегда бесполезно.
Но вопрос в интерфейсах. Я не хотел отвлекаться. Я имею в виду, что начиная с Java 8 мы можем также говорить о частных методах и методах по умолчанию в интерфейсах, верно? Так что это обсуждение может быть довольно длинным, если мы захотим. ;)
Несмотря на то, что этот вопрос был задан давно, но я чувствую, что подробное описание проясняет, почему нет необходимости использовать общедоступные абстрактные перед методами и общедоступные статические финальные перед константами интерфейса.
Прежде всего, интерфейсы используются для определения общих методов для набора несвязанных классов, для которых каждый класс будет иметь уникальную реализацию. Следовательно, невозможно указать модификатор доступа как частный, поскольку он не может быть доступен другим классам для переопределения.
Во-вторых, хотя можно инициировать объекты типа интерфейса, но интерфейс реализуется классами, которые его реализуют, а не наследуются. И поскольку интерфейс может быть реализован (реализован) разными несвязанными классами, которые не находятся в одном пакете, модификатор защищенного доступа также недействителен. Так что для модификатора доступа у нас остается только общественный выбор.
В-третьих, интерфейс не имеет реализации данных, включая переменные и методы экземпляра. Если есть логическая причина для вставки реализованных методов или переменных экземпляра в интерфейс, тогда это должен быть суперкласс в иерархии наследования, а не интерфейс. Учитывая этот факт, поскольку ни один метод не может быть реализован в интерфейсе, все методы в интерфейсе должны быть абстрактными.
В-четвертых, интерфейс может включать только константу в качестве членов данных, что означает, что они должны быть окончательными, и, конечно же, конечные константы объявляются как статические, чтобы сохранить только один их экземпляр. Следовательно, 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. К сожалению, «неявно общедоступное» поведение когда-либо было разрешено, поскольку теперь оно, вероятно, останется для обратной совместимости и приведет к путанице, что отсутствие модификатора доступа означает «общедоступный» в интерфейсах и «пакет» в других местах.
Это плохо, потому что написание его как общедоступного подразумевает, что может не является общедоступным.