Domanda Come prendi la decisione di definire una variabile "privata"?


Ho partecipato a un colloquio di lavoro. L'intervistatore mi ha chiesto perché hai bisogno di variabili private. Se ottieni qualcosa definendo una variabile privata, non puoi ottenere lo stesso definendo qualsiasi altro modificatore di accesso definito in java?

Secondo Java Specification Languages,

Un membro o un costruttore privato della classe è accessibile solo all'interno del corpo di
classe di livello superiore (7.6) che racchiude la dichiarazione del membro o del costruttore.
Non è ereditato da sottoclassi.

Ma, se sto progettando una classe, come posso prendere una decisione per definire una variabile "privata"?


14
2017-11-24 12:20


origine


risposte:


Limitando l'accesso ad "altro codice" (magari scritto / mantenuto da altri), sei più libero di cambiarlo in futuro senza doversi preoccupare di rompere qualche altro codice che si basa su di esso.

La domanda non è "dovrei renderlo privato?", Ma piuttosto "c'è bisogno che questo sia non privato?". C'è qualche altro codice che probabilmente avrà bisogno di accedere alla variabile?

Se ciò si verifica, si assegna l'accesso corretto (possibilmente tramite Getter / setter) e si accetta che le modifiche ad esso saranno difficili. Altrimenti lo lasci privato.


40
2017-11-24 12:23



Penso che dovresti guardarlo dall'altra direzione: perché dovresti rendere una variabile tutt'altro che privata? L'incapsulamento corretto significa nascondere i dettagli dell'implementazione, quindi l'impostazione predefinita dovrebbe essere rendere privati ​​i campi.


11
2017-11-24 12:23



In sostanza, una volta che si crea una variabile public, sei impegnato e non puoi mai tornare indietro su questa decisione. Ogni cambiamento futuro cambierebbe l'interfaccia pubblica della tua classe, il che a sua volta significa che ogni utilizzo di quella classe deve essere cambiato. Per un'API pubblica, questo è impensabile; la tua libreria ha effettivamente rotto la compatibilità con le versioni precedenti.

Anche per le classi utilizzate privatamente, questo è un po 'un grosso problema.

Quindi quando cambieresti mai l'ambito di una variabile private nel futuro? Ci sono molte ragioni plausibili per questo. La cosa più semplice è che la tua classe potrebbe aver bisogno di fare qualcosa ogni volta che il valore della variabile viene modificato (ad esempio, registra la modifica o aggiorna altre variabili di conseguenza). Oppure, in seguito, decidi che la variabile non è affatto necessaria e che il valore richiesto dall'utente deve essere calcolato al volo.

Se stai leggendo o impostando una variabile direttamente, non è possibile. Invece, la tua classe ha bisogno di costringere l'utente a chiamare un getter / setter, vietando l'accesso diretto alla variabile e offrendo al suo posto appropriati metodi pubblici getter / setter.

Perché in generale puoi mai prevedere tali cambiamenti futuri, è diventata una pratica accettata da fare no variabile public. Ogni variabile dovrebbe essere private (o almeno interno).

(C'è un'eccezione: in alcuni casi, final le variabili possono essere fatte in modo sicuro public. Ad esempio, le costanti enum-like sono spesso implementate come public final variabili nelle librerie Java perché non cambieranno mai, e non è richiesto alcun controllo di accesso poiché sono di sola lettura comunque).


8
2017-11-24 13:43



Una regola generale è quella di ridurre l'ambito di variabili e metodi. Più cose si mantengono private più facilmente è possibile cambiare la classe senza causare problemi in altre parti del sistema (ad es. Ridurre l'accoppiamento).

Quindi, come regola generale, il privato dovrebbe essere predefinito


7
2017-11-24 12:23



Se ottieni qualcosa definendo una variabile privata, non puoi ottenere lo stesso definendo qualsiasi altro modificatore di accesso definito in java?

Sì. È vero. Qualunque private può essere cambiato in public (o protected e così via) e il programma verrà compilato ed eseguito proprio come prima.

I modificatori di accesso sono disponibili per i programmatori e lo aiutano a definire correttamente l'interfaccia della classe. Dai un'occhiata a l'articolo di Wikipedia sull'incapsulamento.


3
2017-11-24 12:25



Quindi, devi chiederti perché deve essere privato. Quindi, che ne dici di usare la verità per idea di contraddizione.

Può essere pubblico?  Se la risposta è, non vuoi che le persone siano in grado di accedere e modificare direttamente l'attributo, quindi non può essere pubblico.

Può essere predefinito?  Se la risposta è, non si desidera che lo stesso pacchetto sia in grado di accedere e modificare direttamente l'attributo, quindi non può essere predefinito.

Può essere protetto Se la risposta è, non vuoi che le sottoclassi accedano e modificino direttamente l'attributo, quindi non può essere protetto.

Pertanto, se tutte le risposte sono No (e devi determinare le risposte del motivo per cui non vuoi l'accesso in questi scenari), allora deve essere privato.

La domanda è chiedere, capisci veramente cosa ti danno i modificatori e come possono essere acceduti, e non rendere ciecamente privati ​​di tutto, e creare setter e getter, perché è quello che ti hanno insegnato il tuo docente / libro / manuale.


3
2017-11-24 12:25



il membro è privato nei casi:

  1. è una proprietà, la sua lettura e scrittura dovrebbero essere eseguite solo tramite metodi di classe
  2. ha senso solo nel contesto dell'oggetto e da nessun'altra parte
  3. non dovrebbe essere visibile dall'esterno della classe

L'oggetto di tale progettazione è l'incapsulamento, il che significa che l'implementazione della classe è nascosta dal codice client. Migliora la leggibilità, la manutenibilità e la testabilità del codice.


2
2017-11-24 12:24



Il punto principale delle classi è incapsulare dati e comportamenti e nascondere l'implementazione interna, esponendo al contempo l'API pulita, semplice e utile esternamente.

Ci sono due cose diverse da considerare: contratto pubblico (API) e dati privati.

  1. Campi privati: sono i tuoi dati privati, che non vuoi esporre esternamente a causa di: sicurezza e integrità.

  2. Metodi privati: le funzioni di utilità per rendere il codice più leggibile e gestibile.

  3. Metodi pubblici: un contratto (interfaccia, API) che esponi alle altre persone. Questo è ciò che rende le tue lezioni utili.

  4. Campi pubblici: non usare questo. Espone solo una parte dei tuoi dati interni. Per le classi semplici potrebbe essere ok, mentre per le classi complesse con campi interdipendenti questo è un grande no-no. Per esporre le funzionalità è necessario utilizzare metodi pubblici (punto 3).


1
2017-11-24 12:35



Molti di questi commenti si applicano a classi, metodi e costruttori interni / nidificati.

In sostanza, si desidera rendere l'accesso il più limitato possibile senza creare eccessiva complessità. Se riesci a creare qualcosa di privato o statico, te lo suggerisco. Se riesci a fare un field final, questo di solito aiuta anche a migliorare la chiarezza.

Quando un campo o un membro è privato puoi vedere immediatamente dove viene utilizzato e quando non è più utilizzato.


0
2017-11-24 12:28