2015-05-02 12 views
5

Java 8 ha introdotto metodi predefiniti e statici sulle interfacce. Così ora puoi avere implementazioni concrete nell'interfaccia sia usando metodi predefiniti che statici.Motivo dell'aggiunta di metodi predefiniti e statici nelle interfacce

La ragione per cui Java ha affermato di aggiungere questi due nuovi tipi di metodi è "garantire la compatibilità binaria con il codice scritto per le versioni precedenti di tali interfacce".

La mia domanda:

  • Perché distorcere il concetto originale interfaccia che supponiamo di essere completamente astratti al fine di sostenere i problemi architettonici esistenti?
  • Qual è la differenza tra l'utilizzo di una classe astratta e la nuova versione dell'interfaccia oltre alla capacità di una classe di estendere più interfacce?
+2

Possibile duplicato di http://stackoverflow.com/questions/22591499/che-sono-delle-differenze-delle-serie astratte-e-interfacce-in-java-8 – Vulcan

+0

@Vulcan la mia domanda è destinata all'uso degli aggiornamenti di java 8 e non della differenza tra astratto e interfaccia –

risposta

7

La ragione per cui java ha affermato di aggiungere questi due nuovi tipi di metodi è "garantire la compatibilità binaria con il codice scritto per le versioni precedenti di tali interfacce".

Si applica solo ai metodi predefiniti (non ai metodi statici) e omette alcuni contesti. Da Goetz, State of the Lambda:

Lo scopo dei metodi predefiniti ... è quello di consentire l'evoluzione delle interfacce in modo compatibile dopo la loro pubblicazione iniziale.

L'obiettivo principale è quello di permettere interfaccia evoluzione, cioè l'aggiunta di nuovi metodi. Se un nuovo metodo viene aggiunto a un'interfaccia, le classi esistenti che implementano l'interfaccia mancherebbero un'implementazione, che sarebbe incompatibile. Per essere compatibile, un'implementazione deve venire da qualche parte, quindi viene fornita con metodi predefiniti.

Perché distorcere l'interfaccia concetto originale che suppone di essere completamente astratto per supportare i problemi architettonici esistenti?

L'intento principale di un'interfaccia Java è quello di specify a contract che ogni classe può implementare senza dover modificare la propria posizione nella gerarchia delle classi. È vero che, prima di Java 8, le interfacce erano puramente astratte.Tuttavia, questa non è una proprietà essenziale delle interfacce. Anche quando sono inclusi i metodi predefiniti, un'interfaccia nel suo cuore specifica ancora un contratto sulla classe di implementazione. La classe di implementazione può sovrascrivere i metodi predefiniti, quindi la classe ha ancora il completo controllo della sua implementazione. (Si noti inoltre che default methods cannot be final.)

Qual è la differenza tra l'utilizzo di una classe astratta e la nuova versione dell'interfaccia altro che la capacità di una classe di estendere più interfacce?

La capacità di una classe di estendere più interfacce è strettamente correlata a un'altra differenza tra interfacce e classi astratte, vale a dire che le interfacce non possono contenere stato. Questa è la difficoltà principale nel consentire l'ereditarietà multipla: se una superclasse dovesse apparire più volte nella discendenza di una classe, lo stato della superclasse apparirà solo una o più volte? (Questo è il cosiddetto "problema dei diamanti".)

Un'altra differenza è che le classi astratte possono definire metodi e campi da condividere con sottoclassi, ma non con i chiamanti, utilizzando livelli di accesso protetti e pacchetti-privati. Le interfacce possono avere solo metodi pubblici.

(In Java 9, è stato aggiunto il supporto per i metodi privati. Questo è utile per la condivisione di implementazione tra predefinite o statici metodi di un'interfaccia.)

Infine, metodi statici nelle interfacce non influiscono ereditarietà di classe, né fanno parte del contratto dell'interfaccia. Sono semplicemente un modo di organizzare i metodi di utilità in modo più conveniente. Ad esempio, un uso comune di metodi statici in un'interfaccia è per metodi di produzione statici. Se i metodi statici non erano consentiti nelle interfacce, i metodi di factory static dovevano essere messi su una classe companion. Consentire metodi statici nelle interfacce consente di raggruppare tali metodi con l'interfaccia stessa, quando ciò è appropriato.

2

Il problema è che non è possibile estendere un'interfaccia con un nuovo metodo senza compromettere la compatibilità. Le classi esistenti non implementano il metodo e pertanto non vengono eseguite con la nuova versione di codice che utilizza questo metodo.

Questo era un grosso problema per la libreria di classi Java in quanto non è possibile aggiungere spesso i metodi richiesti nelle interfacce di base (come le raccolte). Questo era il driver principale per l'implementazione dei metodi predefiniti per le interfacce.

La differenza tra questo nuovo metodo e l'utilizzo di una classe astratta (che in alcuni casi è un buon modello per questo problema) è che non è possibile ereditare da più classi astratte. Ma puoi facilmente implementare più interfacce.

I metodi statici nelle interfacce sono meno chiari, penso che siano qui per aiutarti a implementare i metodi predefiniti (se due metodi predefiniti hanno lo stesso codice, entrambi possono chiamare un metodo statico).