Java Language
Getter e setter
Ricerca…
introduzione
Aggiungere getter e setter
L'incapsulamento è un concetto base in OOP. Si tratta di avvolgere dati e codice come una singola unità. In questo caso, è buona norma dichiarare le variabili come private
e quindi accedervi tramite Getters
e Setters
per visualizzarle e / o modificarle.
public class Sample {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Non è possibile accedere a queste variabili private direttamente dall'esterno della classe. Quindi sono protetti da accessi non autorizzati. Ma se vuoi vederli o modificarli, puoi usare Getters e Setter.
getXxx()
metodo getXxx()
restituirà il valore corrente della variabile xxx
, mentre è possibile impostare il valore della variabile xxx
utilizzando setXxx()
.
La convenzione di denominazione dei metodi è (nella variabile di esempio è chiamata variableName
):
Tutte le variabili non
boolean
getVariableName() //Getter, The variable name should start with uppercase setVariableName(..) //Setter, The variable name should start with uppercase
variabili
boolean
isVariableName() //Getter, The variable name should start with uppercase setVariableName(...) //Setter, The variable name should start with uppercase
I getter e i setter pubblici fanno parte della definizione di proprietà di un bean Java.
Usare un setter o un getter per implementare un vincolo
Setter e Getter consentono a un oggetto di contenere variabili private a cui è possibile accedere e modificarle con restrizioni. Per esempio,
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
if(name!=null && name.length()>2)
this.name = name;
}
}
In questa classe Person
, c'è una singola variabile: name
. È possibile accedere a questa variabile utilizzando il metodo getName()
e modificata utilizzando il metodo setName(String)
, tuttavia, l'impostazione di un nome richiede che il nuovo nome abbia una lunghezza maggiore di 2 caratteri e non sia null. L'uso di un metodo setter invece di rendere pubblico il name
della variabile consente ad altri di impostare il valore del name
con determinate restrizioni. Lo stesso può essere applicato al metodo getter:
public String getName(){
if(name.length()>16)
return "Name is too large!";
else
return name;
}
Nel metodo getName()
modificato sopra, il name
viene restituito solo se la sua lunghezza è minore o uguale a 16. In caso contrario, viene restituito "Name is too large"
. Ciò consente al programmatore di creare variabili che siano raggiungibili e modificabili come desiderano, impedendo alle classi client di modificare indesideratamente le variabili.
Perché usare getter e setter?
Considera una classe base contenente un oggetto con getter e setter in Java:
public class CountHolder {
private int count = 0;
public int getCount() { return count; }
public void setCount(int c) { count = c; }
}
Non possiamo accedere alla variabile count
perché è privata. Ma possiamo accedere ai metodi getCount()
e setCount(int)
perché sono pubblici. Per alcuni, questo potrebbe sollevare la domanda; perché introdurre l'intermediario? Perché non limitarsi a renderle pubbliche?
public class CountHolder {
public int count = 0;
}
A tutti gli effetti, questi due sono esattamente gli stessi, dal punto di vista della funzionalità. La differenza tra loro è l'estensibilità. Considera cosa dice ogni classe:
- Primo : "Ho un metodo che ti darà un valore
int
e un metodo che imposterà quel valore su un altroint
". - Secondo : "Ho un
int
che puoi impostare e ottenere come ti pare."
Questi potrebbero sembrare simili, ma il primo è in realtà molto più custodito nella sua natura; esso permette solo di interagire con la sua natura interna in quanto impone. Questo lascia la palla nel suo campo; può scegliere come si verificano le interazioni interne. Il secondo ha esposto esternamente la sua implementazione interna e ora non è solo incline agli utenti esterni, ma, nel caso di un'API, si impegna a mantenere tale implementazione (o altrimenti a rilasciare un'API compatibile non retrocompatibile).
Consideriamo se vogliamo sincronizzare l'accesso alla modifica e all'accesso al conteggio. Nel primo, questo è semplice:
public class CountHolder {
private int count = 0;
public synchronized int getCount() { return count; }
public synchronized void setCount(int c) { count = c; }
}
ma nel secondo esempio, questo è ora quasi impossibile senza passare e modificare ogni luogo in cui viene fatto riferimento alla variabile count
. Peggio ancora, se questo è un oggetto che stai fornendo in una biblioteca per essere consumato da altri, non hai un modo di eseguire quella modifica, e sei costretto a fare la difficile scelta di cui sopra.
Quindi elemosina la domanda; le variabili pubbliche sono sempre una buona cosa (o, almeno, non sono cattive)?
Non sono sicuro Da un lato, è possibile visualizzare esempi di variabili pubbliche che hanno superato la prova del tempo (IE: la variabile out
a cui fa riferimento in System.out
). Dall'altro, fornire una variabile pubblica non dà alcun beneficio al di fuori del sovraccarico estremamente minimo e della potenziale riduzione del prolisso. La mia linea guida qui sarebbe che, se hai intenzione di rendere pubblica una variabile, dovresti giudicarla contro questi criteri con estremo pregiudizio:
- La variabile dovrebbe avere alcuna ragione plausibile per cambiare mai nella sua attuazione. Questo è qualcosa che è estremamente facile da rovinare (e, anche se lo fai nel modo giusto, i requisiti possono cambiare), motivo per cui i getter / setter sono l'approccio comune. Se si ha una variabile pubblica, è necessario pensarci sopra, specialmente se rilasciata in una libreria / framework / API.
- La variabile deve essere referenziata abbastanza frequentemente che i guadagni minimi derivanti dalla riduzione della verbosità lo giustificano. Non penso nemmeno che l'overhead per l'utilizzo di un metodo rispetto al riferimento diretto debba essere considerato qui. È troppo trascurabile per quello che valuterei prudentemente per il 99,9% delle applicazioni.
Probabilmente c'è più di quello che non ho considerato in cima alla mia testa. Se hai dubbi, usa sempre getter / setter.