2009-05-24 10 views
39

Qual è il motivo per cui in Java, un membro con un modificatore "protetto" non può essere accessibile solo dalla stessa classe e dalle sottoclassi, ma anche da tutti nello stesso pacchetto?Perché il modificatore "protetto" in Java consente l'accesso ad altre classi nello stesso pacchetto?

mi chiedo circa le ragioni di progettazione linguaggio, non applicazioni reali (ad esempio, test)

+10

+1 Francamente voglio sapere anche il perché. Mi ha sempre colpito come una delle decisioni progettuali più stupide in Java. – cletus

+1

@cletus: Più ci penso e più arrivo alla conclusione che "pacchetto privato" era un'idea non ben pensata. Per "pacchetto privato" per il lavoro effettivo e offrire qualsiasi tipo di protezione reale, i pacchetti dovrebbero essere compilati all'interno di una singola unità di compilazione. E uno non dovrebbe essere in grado di migliorarli in seguito. – Martin

risposta

22

Questo progetto si basa sull'idea che il pacchetto è l'unità appropriata, curato e liberato da una squadra internamente coerenti; i rapporti di ereditarietà hanno molto meno a che fare con chi sta mantenendo e rilasciando cosa quando.

+1

Grazie per la risposta. Ovviamente non funziona perché nessuno ti impedisce di distribuire un pacchetto su più barattoli e con esso su più team. Quindi è un'altra bella idea non completamente pensata. Qualcosa di Java è pieno di. – Martin

7

Fondamentalmente ha a che fare con la visualizzazione di un pacchetto come unità controllata api (da qui la raccomandazione di avviare il pacchetto con il nome di dominio - univocità globale garantita), quindi la visibilità cresce da privato -> pacchetto-privato -> protetto -> pubblico. Se protetto non fosse un aumento rispetto al pacchetto-privato, piuttosto un diverso tipo di visibilità, ci sarebbe un modo per combinare i due tipi di visibilità quando necessario.

+0

Ma nessuno ti impedisce di aggiungere una nuova classe a un pacchetto già esistente. Quindi "pacchetto privato" e con esso "protetto" è solo una raccomandazione per i programmatori. Entrambi non offrono alcuna protezione reale dai programmatori malintenzionati/disperati che desiderano/devono chiamare il metodo. - "protetto" come in C++ dovrebbe almeno forzare l'uso di una sottoclasse - ma in Java non hai nemmeno bisogno di farlo. – Martin

1

Dati i livelli progressivi di accesso, privato, pacchetto, protetto e pubblico, sarebbe inutilmente limitante se fosse protetto quindi pacchetto poiché ciò mi obbligherebbe a consentire l'accesso a sottoclassi per concedere altri membri dello stesso pacchetto. Eppure, intuitivamente, dovrebbe essere che altre classi nello stesso pacchetto siano più affidabili di altre classi "là fuori". Così protetto è tra pacchetto e pubblico in quanto consente una più ampia esposizione di accesso.

Penso che la ragione di base si basi sull'intuizione che esiste un livello base di "fiducia" tra le classi nello stesso pacchetto; puoi ragionevolmente aspettarti che facciano la cosa giusta l'uno con l'altro - nella maggior parte dei casi il pacchetto sarà sotto la responsabilità di un singolo ingegnere o team, quindi dovrebbe esserci una coerente armonia di design.

+0

Questa è la teoria. Ma nella pratica questo sarebbe vero solo quando un pacchetto dovrebbe essere compilato in una singola unità di compilazione e non potrebbe essere migliorato all'esterno. Ma non è questo il caso e quindi, con l'aiuto di una classe di delegati snella, qualsiasi metodo "pacchetto privato" può essere reso pubblico. Un suggerimento per il programmatore ma non una vera protezione. – Martin

+0

@martin: solo se si pubblica il pacchetto senza chiuderlo, la capacità risolve questo particolare problema. –

+0

"sigillare il pacchetto" - non ne ho mai sentito parlare ma sembra interessante. ** Dimmi di più! ** (alcune parole per aiutarmi su google i dettagli sono sufficienti) – Martin

20

I modificatori sono ben descritti at http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html. Da lì vediamo questa figura.

Modifier  Class  Package Subclass World 
public   Y   Y   Y   Y 
protected  Y   Y   Y   N 
no modifier  Y   Y   N   N 
private   Y   N   N   N 

Da questo il motivo della decisione di progettazione è ovvio: è avere una bella matrice simmetrica.

+4

Sarebbe comunque simmetrico ... –

+0

Grazie per questo tavolo. – Marin

+0

@ Michael Myers: Beh, no, non sarebbe comunque simmetrico. È simmetrico per una ragione. – Glenn

13

In Java 1.0 c'era un quinto modificatore di accesso: private protected. Questo era protected senza l'accesso predefinito. Apparentemente non ha mai funzionato correttamente ed è stato rilasciato nel 1.1. Quindi sembra che lo protected sia definito nel modo in cui l'ordinamento totale sembra essere spurio. Il modificatore di accesso module in Java 7 presenta alcune domande di progettazione in quest'area.

Dato che si pensava che sarebbe una buona idea per il modificatore di accesso predefinito per i membri di essere "pacchetto privata", sembra ragionevole che protected dovrebbe avere essere almeno questo livello di accesso. Per i miei soldi, lo protected non si paga per niente nella lingua.

+0

Non ne ho mai sentito parlare, ma sono entrato in Java a 1.1 ... Grazie! – Uri

+0

E dal momento che nessuno ti impedisce di aggiungere più classi a un pacchetto in un file jar diverso, "pacchetto privato" non è tutto ciò che è privato. Così com'è: Qualsiasi cosa a parte il privato e il pubblico è più o meno un suggerimento per il programmatore ma nessuna vera protezione. – Martin

0

Java segue i suoi principi di progettazione su se stesso. Cosa succede quando provi a ridurre/restringere l'ambito del metodo pubblico in una sottoclasse? si ottiene un errore. Java modificatori portata livelli seguono: private < (default) < protetto < pubblico

Tutte le classi nel pacchetto si suppone di essere amichevole perché lavorano insieme. Per rendere un membro disponibile nel pacchetto è definito nell'ambito di default.

Una sottoclasse può risiedere al di fuori del pacchetto, seguendo ancora una volta i livelli di ambito: private < (default) < protetto < pubblico - Non possiamo restringere il campo di applicazione. Protetto è un ambito più ampio rispetto a quello predefinito, quindi Java non contraddice le proprie linee guida. Pertanto, un membro protetto sarà disponibile nell'ambito di default. Inoltre: pacchetto classe < <.

Si prega di non limitare i modificatori solo alla visibilità, ma anche l'ereditarietà, la struttura sono in funzione contemporaneamente e li aggiungono anche all'immagine. Se questo era vero: privato < protetto < (predefinito) < pubblico. quindi tutte le sottoclassi dovrebbero risiedere nello stesso pacchetto, quindi perché è necessario ereditare è possibile accedere a tutto come l'ambito predefinito è lì applicabile a livello di pacchetto. L'ambito predefinito avrebbe perso il suo valore e quindi l'ereditarietà.

Problemi correlati