Czy metody interfejsu Java powinny być deklarowane z publicznym modyfikatorem dostępu lub bez niego?

292

Czy metody w interfejsie Java powinny być deklarowane z publicmodyfikatorem dostępu lub bez niego ?

Technicznie nie ma to oczywiście znaczenia. Metoda klasowa, która implementuje „an” interfacejest zawsze public. Ale jaka jest lepsza konwencja?

Sama Java nie jest w tym spójna. Patrz na przykład Collectionvs. Comparablelub Futurevs. ScriptEngine.

Benno Richters
źródło
22
Jest źle, ponieważ pisanie go jako publicznego sugeruje, że może być niepubliczne
Pacerier,
8
Powinieneś unikać zbędnej składni dowolnej formy.
Markiz Lorne
3
@Pacerier, chociaż zgadzam się, że publicw tym kontekście nie należy go używać , domyślne metody interfejsu mogą teraz (w java 9) być prywatne. Sugeruję usunięcie komentarza, ponieważ jest przestarzały.
aioobe,
2
Tak, rzeczy mogą ulec zmianie w Javie 9. „Pisanie jako publiczne oznacza, że może być niepubliczne” . Ponieważ dokładnie , że wydaje się być możliwe w Javie 9, ten argument jest teraz w korzyść rzeczywiście wypisywanie public.
MC Cesarz

Odpowiedzi:

334

JLS czyni to jasne:

Dozwolone jest, ale odradzane ze względu na styl, nadmiarowe określanie publici / lub abstractmodyfikatora dla metody zadeklarowanej w interfejsie.

Jon Skeet
źródło
6
Powyższy link JLS dotyczył Java 7 w momencie, gdy go czytałem. Po komentarzach na temat Java 9 dopuszczających metody niepubliczne, chciałem tylko potwierdzić, że nadal istnieje bardzo podobne sformułowanie dla SE9 JLS . ( publicczęść jest taka sama, and/or abstractczęść została usunięta)
OzgurH
3
Nadal prawdziwe w SE11 JLS
Ortomala Lokni
44

Modyfikator publiczny powinien zostać pominięty w interfejsach Java (moim zdaniem).

Ponieważ nie dodaje żadnych dodatkowych informacji, po prostu odwraca uwagę od ważnych rzeczy.

Większość przewodników po stylach zaleca, abyś je pomijał, ale oczywiście najważniejszą rzeczą jest zachowanie spójności w całej bazie kodu, a zwłaszcza dla każdego interfejsu. Poniższy przykład może łatwo pomylić osobę, która nie jest w 100% biegła w Javie:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
Rasmus Faber
źródło
3
Czy masz link do takiego przewodnika po stylu?
Benno Richters
9
Spójność jest zdecydowanie najważniejszą rzeczą i jest odpowiedzią na 99% tego typu pytań.
SCdF
Uzgodniona zgodność: spójność. Coś dla twoich standardów kodowania dokumentuje chłopaki :)
JeeBee
2
Bno: Jednym z przykładów jest specyfikacja języka Java, innym jest Checkstyle.
Rasmus Faber
9

Pomimo tego, że pytanie to zostało zadane dawno temu, ale uważam, że wyczerpujący opis wyjaśniłby, dlaczego nie ma potrzeby używania publicznego streszczenia przed metodami i publicznego statycznego finału przed stałymi interfejsem.

Przede wszystkim interfejsy służą do określania wspólnych metod dla zbioru niepowiązanych klas, dla których każda klasa będzie miała unikalną implementację. Dlatego nie można określić modyfikatora dostępu jako prywatnego, ponieważ nie można uzyskać do niego dostępu przez inne klasy, które mają zostać zastąpione.

Po drugie, chociaż można inicjować obiekty typu interfejsu, ale interfejs jest realizowany przez klasy, które go implementują i nie są dziedziczone. Ponieważ interfejs może zostać zaimplementowany (zrealizowany) przez różne niepowiązane klasy, które nie znajdują się w tym samym pakiecie, chroniony modyfikator dostępu również nie jest prawidłowy. Tak więc dla modyfikatora dostępu pozostaje nam tylko wybór publiczny.

Po trzecie, interfejs nie ma żadnej implementacji danych, w tym zmiennych i metod instancji. Jeśli istnieje logiczny powód, aby wstawić zaimplementowane metody lub zmienne instancji do interfejsu, musi to być nadklasa w hierarchii dziedziczenia, a nie interfejs. Biorąc to pod uwagę, ponieważ żadna metoda nie może być zaimplementowana w interfejsie, dlatego wszystkie metody w interfejsie muszą być abstrakcyjne.

Po czwarte, interfejs może zawierać tylko stałą jako elementy danych, co oznacza, że ​​muszą one być ostateczne, a stałe końcowe są oczywiście deklarowane jako statyczne, aby zachować tylko jedną ich instancję. Dlatego statyczny finał jest również koniecznością dla stałych interfejsu.

Podsumowując, chociaż użycie publicznego abstraktu przed metodami i publicznego statycznego finału przed stałymi interfejsem jest poprawne, ale ponieważ nie ma innych opcji, uważa się je za zbędne i nieużywane.

Leo The Four
źródło
7

Wraz z wprowadzeniem private, static, defaultmodyfikatory dla metod interfejsu w Javie 8/9, robi się bardziej skomplikowane i mają tendencję do myślenia, że pełne deklaracje są bardziej czytelne (wymaga Java 9 skompilować):

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() {}

}
Werner Thumann
źródło
5

Unikałbym umieszczania modyfikatorów, które są stosowane domyślnie. Jak wskazano, może to prowadzić do niespójności i zamieszania.

Najgorsze, co widziałem, to interfejs z metodami zadeklarowanymi abstract...

PhiLho
źródło
5

Użyłem metod deklaracji z publicmodyfikatorem, ponieważ dzięki temu kod jest bardziej czytelny, szczególnie z podświetlaniem składni. W naszym najnowszym projekcie zastosowaliśmy Checkstyle, który wyświetla ostrzeżenie z domyślną konfiguracją publicmodyfikatorów metod interfejsu, więc przełączyłem się na ich pominięcie.

Nie jestem więc do końca pewien, co jest najlepsze, ale jedną rzeczą, której tak naprawdę nie lubię, jest używanie public abstractmetod interfejsu. Eclipse robi to czasami podczas refaktoryzacji za pomocą „Extract Interface”.

Kretyn
źródło
2
Ale tylko jeśli zaznaczysz dwa pola wyboru, zadeklarujesz metody jako publiczne, abstrakcyjne.
MetroidFan2002
4

Zawsze piszę, czego bym użył, gdyby nie było interfejsu, i pisałem bezpośrednią implementację, tj public. Użyłbym .

JeeBee
źródło
6
Czy jawnie zadeklarowałbyś również wszystkie metody interfejsu jako abstrakcyjne?
Dan Dyer
4
To interfejs, a nie klasa abstrakcyjna. Jeśli chodzi o „publiczne”, to 7 znaków, które wpisałeś, zanim się nad tym zastanowisz, wielka sprawa! I tak to zostanie zdefiniowane w implementacji, która wynosi +1 dla spójności równoważącej -1 dla redundancji.
JeeBee
3

Wolę pomijać, czytam gdzieś, że interfejsy są domyślnie, publici abstract.

Ku mojemu zdziwieniu książka - Head First Design Patterns - używa publicdeklaracji interfejsu i metod interfejsu ... co skłoniło mnie do ponownego przemyślenia i wylądowałem na tym poście.

W każdym razie uważam, że zbędne informacje należy zignorować.

Pradeep Sharma
źródło
1
Aby wyjaśnić, jeśli pominiesz publicmodyfikator dostępu w deklaracji interfejsu, domyślnie nie będzie on publiczny i abstrakcyjny. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad
3

Nie zgadzam się z popularną odpowiedzią, że upublicznienie oznacza, że ​​istnieją inne opcje i dlatego nie powinno tam być. Faktem jest, że teraz w Javie 9 i poza nią istnieją inne opcje.

Myślę, że zamiast tego Java powinna wymusić / wymagać określenia „public”. Dlaczego? Ponieważ brak modyfikatora oznacza dostęp do „pakietu” wszędzie indziej, a posiadanie go jako specjalnego przypadku prowadzi do zamieszania. Jeśli po prostu popełniłeś błąd kompilacji z wyraźnym komunikatem (np. „Dostęp do pakietu nie jest dozwolony w interfejsie.”), Pozbylibyśmy się pozornej niejednoznaczności, jaką daje możliwość pominięcia „publicznego”.

Zwróć uwagę na obecne sformułowanie: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

„Metodę w treści interfejsu można zadeklarować jako publiczną lub prywatną (§6.6). Jeśli nie podano żadnego modyfikatora dostępu, metoda jest domyślnie jawna. Dozwolone jest, ale stylowo zniechęcane, nadmiarowe określenie publicznego modyfikator deklaracji metody w interfejsie. ”

Zobacz, że „prywatny” jest teraz dozwolony. Myślę, że ostatnie zdanie powinno zostać usunięte z JLS. To niefortunne, że zachowanie „niejawnie publiczne” było kiedykolwiek dozwolone, ponieważ prawdopodobnie pozostanie dla wstecznej kompatybilności i doprowadzi do zamieszania, że ​​brak modyfikatora dostępu oznacza „publiczny” w interfejsach i „pakiet” gdzie indziej.

swpalmer
źródło
2

Powód, dla którego metody w interfejsach są domyślnie publiczne i abstrakcyjne, wydaje mi się dość logiczne i oczywiste.

Metoda w interfejsie jest domyślnie abstrakcyjna, aby zmusić klasę implementującą do zapewnienia implementacji, i domyślnie jest publiczna, więc klasa implementująca ma do tego dostęp.

Dodanie tych modyfikatorów do kodu jest zbędne i bezużyteczne i może jedynie prowadzić do wniosku, że brakuje Ci wiedzy i / lub zrozumienia podstaw języka Java.

Iuliana Cosmina
źródło
Ale możesz także zaimplementować metody abstrakcyjne, które mają chroniony dostęp - w klasie abstrakcyjnej. Więc publiczne nie jest wymogiem. Dodanie czegoś jawnego, co jest tym samym, co byłoby domyślne, jest zawsze zbędne, ale nie zawsze jest bezużyteczne.
swpalmer
Ale pytanie dotyczy interfejsów. Nie chciałem dygresji. Mam na myśli, że od wersji Java 8 możemy również rozmawiać o prywatnej i domyślnej metodzie w interfejsach, prawda? Tak więc, jeśli chcemy, dyskusja może być długa. ;)
Iuliana Cosmina
1

To jest całkowicie subiektywne. Pomijam redundantny publicmodyfikator, ponieważ wydaje się, że jest bałaganem. Jak wspomnieli inni - konsekwencja jest kluczem do tej decyzji.

Warto zauważyć, że projektanci języka C # postanowili to wymusić. Zadeklarowanie metody interfejsu jako publicznej w języku C # jest w rzeczywistości błędem kompilacji. Spójność prawdopodobnie nie jest jednak ważna we wszystkich językach, więc myślę, że nie jest to tak naprawdę bezpośrednio związane z Javą.

serg10
źródło
-9

Ludzie będą uczyć się twojego interfejsu z uzupełniania kodu w IDE lub Javadoc, a nie z czytania źródła. Nie ma więc sensu umieszczać słowa „public” w źródle - nikt nie czyta źródła.

Tim Boudreau
źródło
8
Naprawdę muszę się nie zgodzić ze stwierdzeniem, że nikt nie czyta źródła. Myślę, że wiele osób używa na przykład F3 w Eclipse do powiększania kodu. Narzędzia takie jak Maven oferują opcję pobierania źródeł, nie tylko JavaDoc, z jakiegoś powodu.
Benno Richters
To nie jest dokładny powód, aby nie dodawać publicmodyfikatora dostępu do interfejsu. Jest to zgodne z projektem i po dokładnym przemyśleniu.
Mt