Ora che non tutte le dichiarazioni di metodi in un'interfaccia Java sono pubbliche astratte, i metodi dovrebbero essere dichiarati con questi modificatori?


14

A partire da Java 8, i defaultmetodi sono stati introdotti nelle interfacce. In effetti, ciò significa che non tutti i metodi in uno interfacesono abstract.

A partire da Java 9 (forse), i privatemetodi saranno consentiti. Ciò significa che non tutti i metodi in un interfacesono public abstract.

La domanda "I metodi in un'interfaccia Java devono essere dichiarati con o senza il publicmodificatore di accesso?" è stato chiesto a Stack Overflow all'indirizzo /programming/161633/should-methods-in-a-java-interface-be-declared-with-or-without-a-public-access-m

Lì, la maggior parte delle risposte ha sostenuto che public abstractnon dovrebbe essere usato perché nessun metodo in interfacepuò essere altro public abstract. Questo non è più il caso.

Quindi, alla luce di queste nuove funzionalità delle interfacce, le public abstractparole chiave dovrebbero essere utilizzate in una dichiarazione del metodo dell'interfaccia Java?

Nel mio ambiente specifico, avremo persone che sono ingegneri del software esperti, ma non esperti in Java, che leggono di tanto in tanto il codice Java. Ritengo che tralasciando le public abstractparole chiave creerà ora un ulteriore punto di confusione per coloro che non hanno familiarità con la storia di come le interfacce arrivarono ad avere regole diverse per l'uso di queste parole chiave.


5
hai controllato Java 8 JLS? La stessa sezione della vecchia risposta accettata alla SO suggerisce che l'introduzione di metodi predefiniti non ha cambiato la raccomandazione precedente basata sulle stesse considerazioni di ridondanza: "Un metodo di interfaccia privo di un defaultmodificatore o di un staticmodificatore è implicitamente abstract... È consentito, ma scoraggiato dal punto di vista stilistico, specificare ridondante il abstractmodificatore per tale dichiarazione di metodo ". Perché pensi che le cose dovrebbero cambiare?
moscerino

3
Ho pensato che le cose potrebbero cambiare perché le condizioni per un metodo implicitamente abstractstanno diventando sempre più contorte. In Java 9, la stessa frase potrebbe essere "Un metodo di interfaccia privo di un defaultmodificatore o di un staticmodificatore o di un privatemodificatore è implicitamente astratto ..." Inoltre, gli argomenti ausiliari per non usare esplicitamente le parole chiave, vale a dire che tutti i metodi di interfaccia sono public abstract, sono ora discutibili.
David Campbell,

TBH Non capisco il ragionamento alla base dei metodi "predefiniti" e persino i metodi statici vanno oltre lo scopo di ciò che le interfacce sono normalmente destinate a fare. Le interfacce non dovrebbero essere sellate dalla concrezione. Ecco perché sono tipi utili per i riferimenti.
Trixie Wolf

1
I metodi predefiniti di @TrixieWolf consentono alle interfacce di evolversi. In precedenza, e diversamente dalle classi, l'aggiunta di un metodo avrebbe interrotto ogni implementazione; ora, puoi far crescere un'interfaccia fintanto che hai un buon candidato predefinito. Prendere in considerazione l'aggiunta di streama java.util.Collection, o Map.getOrDefault(). L'alternativa è creare una nuova sotto-interfaccia e far abbattere tutti, come Graphics2D, e nessuno è piaciuto!
SusanW,

Risposte:


2

Per espandere la risposta StackOverflow:

  1. Il publicmodificatore di accesso non è necessario perché

    Ogni dichiarazione di metodo nel corpo di un'interfaccia è implicitamente pubblica (§6.6). È consentito, ma scoraggiato dal punto di vista dello stile, specificare in modo ridondante il modificatore pubblico per una dichiarazione di metodo in un'interfaccia. ( Sezione 9.4 )

  2. Il abstractmodificatore di accesso non è necessario perché

    Un metodo predefinito è un metodo dichiarato in un'interfaccia con il modificatore predefinito; il suo corpo è sempre rappresentato da un blocco .

    E...

    Un metodo di interfaccia privo di un modificatore predefinito o di un modificatore statico è implicitamente astratto , quindi il suo corpo è rappresentato da un punto e virgola , non da un blocco.

Dato che i metodi predefiniti hanno un corpo e quelli che non sono intrinsecamente astratti e ogni dichiarazione di metodo su un'interfaccia è intrinsecamente pubblica, non è necessario specificare nessuna parola chiave.


Uno dei commenti su una risposta diceva:

Non farli pensare! Ho sempre aggiunto abstract pubblico prima, nonostante la polizia di stile, perché rendeva le cose chiare e ricordava al lettore. Ora sono confermato perché Java 8 e 9 complicano le cose (user949300)

Un commento sulla domanda StackOverflow (votato 18 volte) rifiuta questo:

È un male perché scriverlo come pubblico implica che può essere non pubblico (Pacerier)

Le implicazioni del codice, in particolare le interfacce, sono importanti.


Il commento che hai citato da StackOverflow è ora obsoleto. Dire che aggiungere il modificatore pubblico è una cattiva scrittura poiché implica che può essere non pubblico è contraddittorio. Il metodo può essere non pubblico.
David Campbell,

@DavidCampbell: Beh, penso che questa domanda potrebbe essere meglio posta dopo l'uscita di Java 9. :) Le specifiche Java appena ancora finalizzate potrebbero rispondere a questa domanda.
Greg Burghardt,

1

La mancanza di un'istruzione di blocco non è sufficiente? Dichiareresti extends Objectanche se è implicito?

Se lo sviluppatore non capisce la ridondanza, è probabile che non comprendano appieno il concetto alla base della funzionalità del linguaggio , che è un problema ancora più grande di essere confuso sui modificatori.

Lo sviluppatore deve comprendere che lo scopo di un'interfaccia è quello di creare un contratto che definisca come un client può interagire con un oggetto. Ciò suggerisce che qualsiasi metodo in un'interfaccia utilizzata per l'interazione con gli oggetti dovrebbe essere esposto ai client.

Se dichiari un metodo privato, stai dichiarando esplicitamente che quel metodo non è pensato per essere chiamato dai client, che nel caso delle interfacce è qualcosa che non può essere facilmente dedotto.


2
Non farli pensare! Ho sempre aggiunto public abstractprima, nonostante la polizia di stile, perché rendeva le cose chiare e ricordava al lettore. Ora sono confermato perché Java 8 e 9 complicano le cose :-). Java è già molto ridondante.
user949300

1
@ user949300 Aggiungeresti anche extends Objecta ogni classe da cui deriva direttamente Object? Sono le informazioni di cui uno sviluppatore dovrebbe già essere a conoscenza, motivo per cui è dedotto. Meno informazioni sono inutili sullo schermo, più è facile elaborare le informazioni importanti. Spero di averti persuaso a venire dal lato oscuro (Capisci? Perché non si vedono cose implicite). Altrimenti, valeva la pena provare ahah. Alla fine, si riduce a ciò che rende il codice più facile da gestire per lo sviluppatore
Vince Emigh,

@ user949300 In questo modo è più probabile creare confusione su cosa significhi quando i metodi di interfaccia non contengono queste dichiarazioni. cioè se ci sono sviluppatori che imparano Java guardando il tuo codice, hai potenzialmente ostacolato la loro comprensione della sintassi delle dichiarazioni dell'interfaccia.
JimmyJames,

Vince, no, non estenderei Object, anche se non trovo una soluzione quando vedo il codice che lo fa. @JimmyJames, se uno è coerente aggiungendo un estratto pubblico agli elementi che lo sono, non vedo alcuna confusione. Mi sto perdendo qualcosa? OTOH, vedo il tuo punto sul disordine. Ad esempio, non aggiungo finalprima argomenti di metodo a meno che qualcosa di divertente non lo richieda (come una classe interna anonima ecc ...)
user949300

@ user949300 Vuol dire che se un utente era già esposto alla mancanza di modificatori e al motivo dietro di esso, potrebbero mettere in dubbio il motivo per cui i modificatori sono lì quando li vedono, facendoli supporre che potrebbe esserci un motivo reale dietro ad esso solo che essere esplicito . Se non lo vedessi extends Object, non farei una crisi, ma alzano sicuramente una bandiera e mi chiedo perché. Come ho detto nel post, fare queste cose potrebbe implicare che lo sviluppatore potrebbe avere un malinteso su come funziona qualcosa (potrebbe non sapere che tutti gli oggetti si estendono già Object, quindi l'estensione esplicita)
Vince Emigh
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.