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

292

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

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

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

Бенно Рихтерс
источник
22
Это плохо , потому что писать его как общественность предполагает , что это может быть непубличным
Pacerier
8
Вы должны избегать избыточного синтаксиса любой формы.
маркиз Лорн
3
@Pacerier, хотя я согласен с тем, что publicв этом контексте использовать плохо , методы интерфейса по умолчанию теперь могут (с java 9) быть закрытыми. Я предлагаю вам удалить свой комментарий, так как он устарел.
aioobe
2
Да, в Java 9 все может измениться. «Публичная запись подразумевает, что она может быть непубличной» . Поскольку именно это представляется возможным в Java 9, теперь этот аргумент действительно выгоден для записи public.
MC Emperor

Ответы:

334

JLS делает это ясно:

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

Джон Скит
источник
6
Ссылка JLS выше была для Java 7 в то время, когда я ее читал. После комментариев о том, что Java 9 допускает закрытые методы, я просто хотел подтвердить, что очень похожая формулировка все еще существует для SE9 JLS . ( publicчасть такая же, and/or abstractчасть была отброшена)
OzgurH
3
Все еще верно в SE11 JLS
Ортомала Локни
Обновление: Java 13 docs.oracle.com/javase/specs/jls/se13/html/jls-9.html#jls-9.4
Нху Вы
44

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

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

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

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
Расмус Фабер
источник
3
У вас есть ссылка на такое руководство по стилю?
Бенно Рихтерс
9
Согласованность, безусловно, самая важная вещь, и является ответом на 99% этих типов вопросов.
SCDF
Согласовано: последовательность. Что-то для ваших стандартов кодирования документов, ребята :)
JeeBee
2
Bno: Одним из примеров является спецификация языка Java, другим - Checkstyle.
Расмус Фабер
9

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

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

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

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

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

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

Лев четверка
источник
7

С введением 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

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

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

PhiLho
источник
5

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

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

cretzel
источник
2
Но только если вы отметите два флажка, объявите методы как публичные, абстрактные.
MetroidFan2002
4

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

JeeBee
источник
6
Вы также явно объявите все методы интерфейса абстрактными?
Дэн Дайер
4
Это интерфейс, а не абстрактный класс. Что касается «публики», то это 7 символов, которые вы набрали, когда вы думаете об этом, большое дело! И именно так это будет определяться в реализации, которая равна +1 для согласованности, балансируя -1 для избыточности.
JeeBee
3

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

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

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

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

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

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

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

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

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

swpalmer
источник
2

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

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

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

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

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

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

serg10
источник
-9

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

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