Чи слід в інтерфейсі Java оголошувати методи з модифікатором доступу загальнодоступного доступу чи без нього?


292

Чи слід оголошувати методи в інтерфейсі Java із publicмодифікатором доступу або без нього ?

Технічно це не має значення, звичайно. Метод класу, який реалізує, interfaceє завжди public. Але що є кращою умовою?

Сама Java в цьому не відповідає. Дивіться, наприклад, Collectionпроти Comparable, або Futureпроти ScriptEngine.


22
Це погано, оскільки писати його як публічне означає, що воно може бути непублічним
Pacerier

8
Вам слід уникати зайвих синтаксисів будь-якої форми.
Маркіз Лорн

3
@Pacerier, хоча я згоден , що це погано , щоб використовувати publicв цьому контексті, методи інтерфейсу по замовчуванням можуть зараз (з Явою 9) бути приватними. Я пропоную вам видалити свій коментар, оскільки він застарілий.
aioobe

2
Так, у Java 9 все може змінюватися. "Якщо писати це як публічне, це означає, що воно може бути непублічним" . Так точно , що представляється можливим в Java 9, цей аргумент тепер на користь дійсно виписувати public.
MC Імператор

Відповіді:


334

У JLS це ясно:

Дозволено, але не відсторонено в залежності від стилю, надмірно вказати publicта / або abstractмодифікатор для способу, оголошеного в інтерфейсі.


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

3
Все ще вірно в SE11 JLS
Ортомала Локні


44

Загальнодоступний модифікатор повинен бути пропущений в інтерфейсах Java (на мою думку).

Оскільки вона не додає зайвої інформації, вона просто привертає увагу до важливих речей.

Більшість посібників зі стилів рекомендують залишати його поза межами, але, звичайно, найголовніше - це бути послідовними в кодовій базі даних, особливо для кожного інтерфейсу. Наступний приклад може легко заплутати когось, хто не володіє на 100% явою:

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

3
Чи є у вас посилання на такий посібник зі стилів?
Бенно Ріхтерс

9
Послідовність - це, безумовно, найважливіше, і це відповідь на 99% таких типів питань.
SCdF

Погоджена ре: послідовність. Щось для ваших стандартів кодування, документи, хлопці :)
JeeBee

2
Bno: Один приклад - специфікація мови Java, інший - Checkstyle.
Расмус Фабер

9

Незважаючи на те, що це питання було задано давно, але я вважаю, що вичерпний опис пояснив би, чому немає необхідності використовувати публічний конспект перед методами та публічним статичним фіналом перед константами інтерфейсу.

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

По-друге, Хоча можна ініціювати об'єкти типу інтерфейсу, але інтерфейс реалізується класами, які його реалізують і не успадковуються. А оскільки інтерфейс може бути реалізований (реалізований) різними непов'язаними класами, які не знаходяться в одному пакеті, тому модифікатор захищеного доступу також недійсний. Тож для модифікатора доступу нам залишається лише публічний вибір.

По-третє, інтерфейс не має жодної реалізації даних, включаючи змінні екземпляри та методи. Якщо є логічна причина для вставки реалізованих методів або змінних екземплярів в інтерфейс, це повинен бути надкласом в ієрархії спадкування, а не інтерфейсом. Враховуючи цей факт, оскільки жоден метод не може бути реалізований в інтерфейсі, тому всі методи в інтерфейсі повинні бути абстрактними.

По-четверте, інтерфейс може включати в себе лише константи як своїх членів даних, що означає, що вони повинні бути остаточними, і, звичайно, кінцеві константи оголошуються статичними, щоб зберігати лише один примірник. Тому статичний фінал також є необхідним для констант інтерфейсу.

Отже, на закінчення, хоча використання публічного реферату перед методами та публічного статичного фіналу перед константами інтерфейсу є дійсним, але оскільки немає інших варіантів, він вважається зайвим і не використовується.


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...


5

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

Тож я не дуже впевнений, що найкраще, але одне, що мені дуже не подобається, - це використовувати public abstractінтерфейсні методи. Eclipse робить це іноді, коли рефакторинг за допомогою "Extract Interface".


2
Але лише якщо ви встановите два прапорці, декларуйте методи загальнодоступними, абстрактними.
MetroidFan2002

4

Я завжди пишу те, що використовував би, якби не було інтерфейсу, і я писав пряму реалізацію, тобто я б використовував public.


6
Ви також чітко оголосили б усі абстрактні методи інтерфейсу абстрактними?
Дан Дайер

4
Це інтерфейс, а не абстрактний клас. Що стосується "загальнодоступних", це 7 символів, які ви набрали до того часу, як задумаєтесь, велика справа! І це, як це буде визначено і в реалізації, що становить +1 для послідовності, що врівноважує -1 для надмірності.
JeeBee

3

Я вважаю за краще пропускати його, десь читаю, що інтерфейси за замовчуванням, publicі abstract.

На мій подив, книга - Head First 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. Прикро, що "неявна публічна" поведінка коли-небудь була дозволена, оскільки це, ймовірно, залишатиметься для зворотної сумісності і призведе до плутанини, що відсутність модифікатора доступу означає "публічне" в інтерфейсах і "пакет" в інших місцях.


2

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

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

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


Але ви також можете реалізувати абстрактні методи, що захищають доступ - в абстрактному класі. Тож громадськість не є вимогою. Додавання явного, що є тим самим, що було б за замовчуванням, завжди є зайвим, але воно не завжди є марним.
swpalmer

Але питання стосується інтерфейсів. Я не хотів відволікатися. Я маю на увазі, оскільки з Java 8 ми також можемо говорити про приватний і типовий метод в інтерфейсах, правда? Тож ця дискусія може вестись досить довго, якщо ми хочемо. ;)
Юліяна Косміна

1

Це абсолютно суб'єктивно. Я опускаю надлишковий publicмодифікатор, як здається, що це безлад. Як зазначають інші - послідовність є ключем до цього рішення.

Цікаво відзначити, що дизайнери мови C # вирішили застосувати це. Оголошення методу інтерфейсу загальнодоступним на C # - це фактично помилка компіляції. Хоча послідовність, мабуть, не важлива для мов, тому я думаю, що це насправді не стосується Java.


-9

Люди дізнаються ваш інтерфейс із заповнення коду в їх IDE або в Javadoc, а не з читання джерела. Тому немає сенсу ставити "джерело" у джерело - джерело ніхто не читає.


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

Це не точна причина не додавання publicмодифікатора доступу до інтерфейсу. Це задум і після ретельного продумування.
mtk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.