2014-12-08 18 views
29

Facciamo un esempio:Perché Java 8 non consente metodi predefiniti non pubblici?

public interface Testerface { 

    default public String example() { 
     return "Hello"; 
    } 

} 

public class Tester implements Testerface { 

    @Override 
    public String example() { 
     return Testerface.super.example() + " world!"; 
    } 


} 

public class Internet { 

    public static void main(String[] args) { 
     System.out.println(new Tester().example()); 
    } 

} 

abbastanza semplicemente, questo sarebbe stampare Hello world!. Ma dire che stavo facendo qualcos'altro con il valore di ritorno di Testerface#example, ad esempio inizializzando un file di dati e restituendo un valore interno sensibile che non dovrebbe lasciare la classe di implementazione. Perché Java non consente i modificatori di accesso sui metodi di interfaccia predefiniti? Perché non possono essere protetti/privati ​​e potenzialmente elevati da una sottoclasse (simile a come una classe che estende una classe genitore può utilizzare un modificatore più visibile per un metodo sottoposto a override)?

Una soluzione comune si sta spostando su una classe astratta tuttavia nel mio caso specifico, ho un'interfaccia per enumerazione, quindi non si applica qui. Immagino sia stato trascurato o perché l'idea originale dietro le interfacce fosse un "contratto" di metodi disponibili, ma suppongo di voler dare un input su cosa sta succedendo con questo.

ho letto "Why is “final” not allowed in Java 8 interface methods?", in cui si afferma:

L'idea di base di un metodo di default è: si tratta di un metodo di interfaccia con un'implementazione di default, e una classe derivata può fornire una più specifica implementazione

E mi sembra che la visibilità non romperebbe affatto questo aspetto.

Come per la domanda collegata poiché sembra abbia avuto problemi a essere chiusa, una risposta autorevole sarebbe apprezzata in questa materia, piuttosto che in base all'opinione pubblica.

+3

quale sarebbe il significato di un metodo privato in un'interfaccia? – njzk2

+0

@ njzk2 per la domanda "Diciamo che stavo facendo qualcos'altro con il valore di ritorno di Testerface # esempio, per esempio inizializzando un file di dati e restituendo un valore interno sensibile che non dovrebbe lasciare la classe di implementazione". Questa è un'interfaccia per un enum, quindi anche se è un po 'complesso, non direi che ci sono molti modi migliori per quello che sto facendo al di fuori di questa domanda. – Rogue

+0

un metodo privato può essere chiamato solo dalla propria classe. Nel caso di un'interfaccia, significherebbe un metodo che non può essere chiamato. – njzk2

risposta

41

Come abbiamo visto in What is the reason why “synchronized” is not allowed in Java 8 interface methods? e Why is "final" not allowed in Java 8 interface methods?, estendere le interfacce per definire il comportamento è più sottile di quanto potrebbe apparire prima. Si scopre che ognuno dei possibili modificatori ha una propria storia; non è semplicemente una questione di copiare ciecamente da come funzionano le classi. (Questo è almeno evidente col senno di poi, come strumenti per la modellazione OO che lavorano per l'ereditarietà singola non funzionano automaticamente per ereditarietà multipla.)

Cominciamo con la risposta ovvia: interfacce hanno sempre stato limitato al solo avendo pubblico i membri, e mentre abbiamo aggiunto metodi predefiniti e metodi statici alle interfacce in Java 8, ciò non significa che dobbiamo cambiare tutto solo per essere classi "più simili".

A differenza di synchronized e final, che sarebbero stati errori seri per supportare i metodi predefiniti, accessibilità più deboli, soprattutto private, sono caratteristiche ragionevoli da considerare. I metodi di interfaccia privata, sia statici che di istanza (si noti che questi non sarebbero valori predefiniti, poiché non partecipano all'ereditarietà) sono uno strumento perfettamente ragionevole (sebbene possano essere facilmente simulati da classi di helper non pubbliche)

prendere in considerazione l'utilizzo di metodi di interfaccia privata in Java 8; questo è stato per lo più qualcosa che è appena caduto dal fondo della lista a causa di risorse e limiti di tempo. È abbastanza probabile che questa funzione possa riapparire nella lista delle cose da fare un giorno.

I pacchetti e i metodi protetti, tuttavia, sono più complicati di quanto sembrino; la complessità dell'ereditarietà multipla e la complessità del vero significato di protected interagirebbero in tutti i modi non così divertenti. Quindi non terrei il respiro per quello.

Quindi, la risposta breve è che i metodi di interfaccia privata sono qualcosa che avremmo potuto fare in 8, ma non potevamo fare tutto ciò che avrebbe potuto essere fatto e ancora spedito, quindi è stato tagliato, ma potrebbe tornare indietro.

+0

Non è la mancanza di metodi privati ​​sulle interfacce combinati con metodi predefiniti incoraggiano gli sviluppatori a esporre i mutatori? – Jeff

+1

Penso che "incoraggiare" sia la parola sbagliata. Non riesce a scoraggiare. Ci sarebbe piaciuto avere metodi privati ​​in interfacce in 8, ma c'è un limite a quanto puoi fare nel tempo e nelle risorse che hai. –

+20

Buone notizie: i metodi privati ​​nelle interfacce sembrano faranno Java 9. –

Problemi correlati