I metodi in un'interfaccia Java devono essere dichiarati con o senza un modificatore di accesso pubblico?


292

I metodi in un'interfaccia Java devono essere dichiarati con o senza il publicmodificatore di accesso?

Tecnicamente non importa, ovviamente. Un metodo di classe che implementa un interfaceè sempre public. Ma cos'è una convenzione migliore?

Java stesso non è coerente in questo. Si veda ad esempio Collectioncontro Comparable, o Futurecontro ScriptEngine.


22
È un male perché scriverlo come pubblico implica che può essere non pubblico
Pacerier,

8
È necessario evitare la sintassi ridondante di qualsiasi forma.
Marchese di Lorne,

3
@Pacerier, anche se sono d'accordo sul fatto che è male da usare publicin questo contesto, i metodi di interfaccia predefiniti ora possono essere privati ​​(con Java 9). Ti suggerisco di rimuovere il tuo commento in quanto è obsoleto.
aioobe,

2
Sì, le cose sono soggette a modifiche in Java 9. "Scriverlo come pubblico implica che può essere non pubblico" . Poiché esattamente ciò sembra essere possibile in Java 9, questo argomento è ora a beneficio della scrittura public.
MC Emperor

Risposte:


334

Il JLS chiarisce questo punto:

È consentito, ma scoraggiato dal punto di vista dello stile, specificare in modo ridondante publice / o abstractmodificatore per un metodo dichiarato in un'interfaccia.


6
Il link JLS sopra era per Java 7 al momento in cui l'ho letto. Dopo i commenti su Java 9 che consentono metodi non pubblici, volevo solo confermare che una formulazione molto simile è ancora lì per SE9 JLS . ( publicparte è la stessa, and/or abstractparte è stata abbandonata)
OzgurH,

3
Ancora vero in SE11 JLS
Ortomala Lokni


44

Il modificatore pubblico dovrebbe essere omesso nelle interfacce Java (secondo me).

Dal momento che non aggiunge alcuna informazione aggiuntiva, attira solo l'attenzione dalle cose importanti.

La maggior parte delle guide di stile ti consiglierà di lasciarlo fuori, ma ovviamente la cosa più importante è essere coerenti con la tua base di codice, e specialmente per ogni interfaccia. L'esempio seguente potrebbe facilmente confondere qualcuno, che non conosce al 100% fluentemente Java:

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

3
Hai un link a una tale guida di stile?
Benno Richters,

9
La coerenza è di gran lunga la cosa più importante ed è la risposta al 99% di questo tipo di domande.
SCdF,

Concordato: coerenza. Qualcosa per i vostri standard di codifica documenti ragazzi :)
JeeBee,

2
Bno: un esempio è la specifica del linguaggio Java, un altro è Checkstyle.
Rasmus Faber,

9

Nonostante il fatto che questa domanda sia stata posta molto tempo fa, ma ritengo che una descrizione esaustiva chiarirebbe perché non è necessario utilizzare un estratto pubblico prima dei metodi e un finale statico pubblico prima delle costanti di un'interfaccia.

Innanzitutto le interfacce vengono utilizzate per specificare metodi comuni per un insieme di classi non correlate per le quali ogni classe avrà un'implementazione unica. Pertanto, non è possibile specificare il modificatore di accesso come privato poiché non è possibile accedervi da altre classi.

In secondo luogo, sebbene sia possibile avviare oggetti di un tipo di interfaccia ma un'interfaccia è realizzata dalle classi che la implementano e non ereditata. E poiché un'interfaccia potrebbe essere implementata (realizzata) da diverse classi non correlate che non sono nello stesso pacchetto, pertanto anche il modificatore di accesso protetto non è valido. Quindi per il modificatore di accesso ci resta solo una scelta pubblica.

In terzo luogo, un'interfaccia non ha alcuna implementazione dei dati, comprese le variabili e i metodi dell'istanza. Se esiste una ragione logica per inserire metodi implementati o variabili di istanza in un'interfaccia, allora deve essere una superclasse in una gerarchia di ereditarietà e non un'interfaccia. Considerando questo fatto, poiché nessun metodo può essere implementato in un'interfaccia, quindi tutti i metodi nell'interfaccia devono essere astratti.

In quarto luogo, Interface può includere solo la costante come membri dei dati, il che significa che devono essere finali e, naturalmente, le costanti finali vengono dichiarate come statiche per conservarne solo un'istanza. Pertanto, anche il finale statico è un must per le costanti di interfaccia.

Quindi, in conclusione, sebbene l'uso di abstract pubblici prima dei metodi e di public static final prima delle costanti di un'interfaccia sia valido, ma poiché non ci sono altre opzioni, è considerato ridondante e non utilizzato.


7

Con l'introduzione di private, static, defaultmodificatori per i metodi di interfaccia in Java 8/9, le cose si fanno più complicate e tendo a pensare che le dichiarazioni complete sono più leggibili (ha bisogno di Java 9 per compilare):

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

Eviterei di mettere i modificatori che vengono applicati per impostazione predefinita. Come sottolineato, può portare a incoerenze e confusione.

Il peggio che ho visto è un'interfaccia con i metodi dichiarati abstract...


5

Ho usato i metodi di dichiarazione con il publicmodificatore, perché rende il codice più leggibile, specialmente con l'evidenziazione della sintassi. Nel nostro ultimo progetto, tuttavia, abbiamo utilizzato Checkstyle che mostra un avviso con la configurazione predefinita per i publicmodificatori sui metodi di interfaccia, quindi sono passato a ommetterli.

Quindi non sono davvero sicuro di cosa sia meglio, ma una cosa che non mi piace davvero è usare i public abstractmetodi di interfaccia. A volte Eclipse esegue questa operazione durante il refactoring con "Estrai interfaccia".


2
Ma solo se selezioni le due caselle di controllo dichiari i metodi come pubblici, astratti.
MetroidFan2002,

4

Scrivo sempre quello che userei se non ci fosse un'interfaccia e stavo scrivendo un'implementazione diretta, cioè, avrei usato public.


6
Dichiareresti anche esplicitamente tutti i metodi di interfaccia astratti?
Dan Dyer,

4
È un'interfaccia, non una classe astratta. Per quanto riguarda il "pubblico", sono 7 i caratteri che hai digitato nel momento in cui ci pensi, un grosso problema! Ed è anche come verrà definito nell'implementazione, che è +1 per coerenza che equilibra -1 per ridondanza.
JeeBee,

3

Preferisco saltarlo, ho letto da qualche parte che le interfacce sono di default, publice abstract.

Con mia sorpresa il libro - Head First Design Patterns , sta usando la publicdichiarazione dell'interfaccia e i metodi dell'interfaccia ... che mi hanno fatto ripensare ancora una volta e sono approdato su questo post.

Ad ogni modo, penso che le informazioni ridondanti debbano essere ignorate.


1
Per chiarire, se si omette il publicmodificatore di accesso nella dichiarazione dell'interfaccia, per impostazione predefinita non sarà pubblico e astratto. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad

3

Non sono d'accordo con la risposta popolare, secondo cui avere pubblico implica che ci sono altre opzioni e quindi non dovrebbe esserci. Il fatto è che ora con Java 9 e oltre ci sono altre opzioni.

Penso invece che Java dovrebbe imporre / richiedere che sia specificato "pubblico". Perché? Perché l'assenza di un modificatore significa "pacchetto" di accesso ovunque, e avere questo come caso speciale è ciò che porta alla confusione. Se lo rendessi semplicemente un errore di compilazione con un messaggio chiaro (ad es. "L'accesso al pacchetto non è consentito in un'interfaccia"), elimineremmo l'apparente ambiguità che introduce la possibilità di escludere "pubblico".

Nota l'attuale formulazione su: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Un metodo nel corpo di un'interfaccia può essere dichiarato pubblico o privato (§6.6). Se non viene fornito alcun modificatore di accesso, il metodo è implicitamente pubblico. È consentito, ma scoraggiato come una questione di stile, specificare ridondantemente il pubblico modificatore per una dichiarazione di metodo in un'interfaccia. "

Scopri che IS "privato" è ora consentito. Penso che l'ultima frase avrebbe dovuto essere rimossa dal JLS. È un peccato che il comportamento "implicitamente pubblico" sia mai stato permesso in quanto rimarrà probabilmente per compatibilità retroattiva e porta alla confusione che l'assenza del modificatore di accesso significhi "pubblico" nelle interfacce e "pacchetto" altrove.


2

La ragione per cui i metodi nelle interfacce sono di default pubblici e astratti mi sembra abbastanza logica e ovvia.

Un metodo in un'interfaccia è per impostazione predefinita astratto forzare la classe di implementazione a fornire un'implementazione ed è pubblica per impostazione predefinita, quindi la classe di implementazione ha accesso per farlo.

L'aggiunta di tali modificatori nel codice è ridondante e inutile e può solo portare alla conclusione che non si ha conoscenza e / o comprensione dei fondamenti di Java.


Ma puoi anche implementare metodi astratti che hanno accesso protetto - in una classe astratta. Quindi il pubblico non è un requisito. L'aggiunta di qualcosa di esplicito che è lo stesso di quello che sarebbe il default è sempre ridondante, ma non è sempre inutile.
swpalmer,

Ma la domanda riguarda le interfacce. Non volevo divagare. Voglio dire, da Java 8, possiamo anche parlare di metodo privato e predefinito nelle interfacce, giusto? Quindi questa discussione può essere fatta piuttosto a lungo se vogliamo. ;)
Iuliana Cosmina,

1

È totalmente soggettivo. Ometto il publicmodificatore ridondante in quanto sembra un disordine. Come menzionato da altri, la coerenza è la chiave di questa decisione.

È interessante notare che i progettisti del linguaggio C # hanno deciso di applicare questo. Dichiarare un metodo di interfaccia come pubblico in C # è in realtà un errore di compilazione. La coerenza probabilmente non è importante in tutte le lingue, quindi suppongo che questo non sia realmente rilevante per Java.


-9

Le persone impareranno la tua interfaccia dal completamento del codice nel loro IDE o in Javadoc, non dalla lettura della fonte. Quindi non ha senso mettere "pubblico" nella fonte - nessuno sta leggendo la fonte.


8
Devo davvero essere in disaccordo con l'affermazione secondo cui nessuno sta leggendo la fonte. Penso che molte persone utilizzino ad esempio F3 in Eclipse per ingrandire il codice. Strumenti come Maven offrono la possibilità di scaricare i sorgenti, non solo JavaDoc, per un motivo.
Benno Richters,

Questo non è il motivo esatto per non aggiungere un publicmodificatore di accesso a un'interfaccia. È di progettazione e dopo un attento pensiero dietro di esso.
mtk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.