CodeGym/Java Blog/Random-IT/Getter e setter
John Squirrels
Livello 41
San Francisco

Getter e setter

Pubblicato nel gruppo Random-IT
membri
Ciao! Nelle lezioni precedenti, hai già imparato come dichiarare le tue classi complete con metodi e campi. Nella lezione di oggi parleremo di Getter e Setter in Java. Questo è un progresso serio, ben fatto! Ma ora devo dirti una spiacevole verità. Non abbiamo dichiarato correttamente le nostre classi! Perché? A prima vista, la seguente classe non presenta errori:
public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}
Ma lo fa. Immagina di essere seduto al lavoro e di scrivere questa lezione di gatti per rappresentare i gatti. E poi vai a casa. Mentre sei via, un altro programmatore arriva al lavoro. Crea la sua classe principale , dove inizia a utilizzare la classe Cat che hai scritto.
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Non importa perché l'ha fatto e come è successo (forse il ragazzo è stanco o non ha dormito abbastanza). Qualcos'altro è importante: la nostra attuale classe Cat consente di assegnare ai campi valori assolutamente folli. Di conseguenza, il programma ha oggetti con uno stato non valido (come questo gatto che ha -1000 anni). Quindi quale errore abbiamo fatto quando abbiamo dichiarato la nostra classe? Abbiamo esposto i dati della nostra classe. I campi nome, età e peso sono pubblici. È possibile accedervi ovunque nel programma: è sufficiente creare un oggetto Cat e qualsiasi programmatore ha accesso diretto ai suoi dati tramite l' operatore punto ( . )
Cat cat = new Cat();
cat.name = "";
Qui stiamo accedendo direttamente al campo del nome e impostando il suo valore. Dobbiamo in qualche modo proteggere i nostri dati da interferenze esterne improprie. Di cosa abbiamo bisogno per farlo? Innanzitutto, tutte le variabili di istanza (campi) devono essere contrassegnate con il modificatore private. Private è il modificatore di accesso più rigoroso in Java. Una volta eseguita questa operazione, i campi della classe Cat non saranno accessibili al di fuori della classe.
public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";//error! The Cat class's name field is private!
   }
}
Il compilatore lo vede e genera immediatamente un errore. Ora i campi sono in qualche modo protetti. Ma si scopre che abbiamo chiuso l'accesso forse troppo strettamente: non puoi ottenere il peso di un gatto esistente nel programma, anche se necessario. Anche questa non è un'opzione. Così com'è, la nostra classe è essenzialmente inutilizzabile. Idealmente, dobbiamo consentire una sorta di accesso limitato:
  • Altri programmatori dovrebbero essere in grado di creare oggetti Cat
  • Dovrebbero essere in grado di leggere i dati da oggetti esistenti (ad esempio, ottenere il nome o l'età di un gatto esistente)
  • Dovrebbe anche essere possibile assegnare valori di campo. Ma così facendo, dovrebbero essere consentiti solo valori validi. I nostri oggetti dovrebbero essere protetti da valori non validi (es. età = -1000, ecc.).
Questo è un elenco decente di requisiti! In realtà, tutto ciò si ottiene facilmente con metodi speciali chiamati getter e setter.
Getter e setter - 2
Questi nomi derivano da "get" (cioè "metodo per ottenere il valore di un campo") e "set" (cioè "metodo per impostare il valore di un campo"). Vediamo come appaiono nella nostra classe Cat :
public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       this.weight = weight;
   }
}
Come puoi vedere, sembrano piuttosto semplici :) I loro nomi spesso consistono in "get"/"set" più il nome del campo pertinente. Ad esempio, il metodo getWeight() restituisce il valore del campo peso per l'oggetto su cui viene richiamato. Ecco come appare in un programma:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       String smudgeName = smudge.getName();
       int smudgeAge = smudge.getAge();
       int smudgeWeight = smudge.getWeight();

       System.out.println("Cat's name: " + smudgeName);
       System.out.println("Cat's age: " + smudgeAge);
       System.out.println("Cat's weight: " + smudgeWeight);
   }
}
Uscita console:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
Ora un'altra classe ( Main ) può accedere ai campi Cat , ma solo tramite getter. Nota che i getter hanno il modificatore di accesso pubblico, cioè sono disponibili da qualsiasi parte del programma. Ma per quanto riguarda l'assegnazione di valori? Ecco a cosa servono i metodi setter
public void setName(String name) {
   this.name = name;
}
Come puoi vedere, sono anche semplici. Chiamiamo il metodo setName() su un oggetto Cat , passiamo una stringa come argomento e la stringa viene assegnata al campo del nome dell'oggetto.
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);

       System.out.println("Cat's original name: " + smudge.getName());
       smudge.setName("Mr. Smudge");
       System.out.println("Cat's new name: " + smudge.getName());
   }
}
Qui stiamo usando sia getter che setter. Innanzitutto, utilizziamo un getter per ottenere e visualizzare il nome originale del gatto. Quindi, usiamo un setter per assegnare un nuovo nome ("Mr. Smudge"). E poi usiamo ancora una volta il getter per ottenere il nome (per verificare se è davvero cambiato). Uscita console:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
Quindi qual è la differenza? Possiamo ancora assegnare valori non validi ai campi anche se abbiamo setter:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
Uscita console:
Smudge's age: -1000 years
La differenza è che un setter è un metodo a tutti gli effetti. E a differenza di un campo, un metodo consente di scrivere la logica di verifica necessaria per evitare valori inaccettabili. Ad esempio, puoi facilmente impedire che un numero negativo venga assegnato come età:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age can't be negative!");
   }
}
E ora il nostro codice funziona correttamente!
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
Uscita console:
Error! Age can't be negative!
Smudge's age: 5 years
All'interno del setter, abbiamo creato una restrizione che ci proteggeva dal tentativo di impostare dati non validi. L'età di Smudge non è stata cambiata. Dovresti sempre creare getter e setter. Anche se non ci sono restrizioni sui valori che i tuoi campi possono assumere, questi metodi di supporto non danneggeranno. Immagina la seguente situazione: tu e i tuoi colleghi state scrivendo un programma insieme. Si crea una classe Cat con campi pubblici. Tutti i programmatori li usano come vogliono. E poi un bel giorno ti rendi conto: "Cazzo, prima o poi qualcuno per sbaglio potrebbe assegnare un numero negativo al peso! Bisogna creare i setter e rendere privati ​​tutti i campi!" Fai proprio questo e rompi all'istante tutto il codice scritto dai tuoi colleghi. Dopo tutto, loro'Campi di gatti direttamente.
cat.name = "Behemoth";
E ora i campi sono privati ​​e il compilatore genera un mucchio di errori!
cat.name = "Behemoth";//error! The Cat class's name field is private!
In questo caso, sarebbe meglio nascondere i campi e creare getter e setter fin dall'inizio. Tutti i tuoi colleghi li avrebbero usati. E se in ritardo ti rendessi conto che dovevi in ​​qualche modo limitare i valori del campo, avresti potuto semplicemente scrivere l'assegno all'interno del setter. E il codice di nessuno verrebbe decifrato. Ovviamente, se vuoi che l'accesso a un campo sia solo "di sola lettura", puoi creare solo un getter per esso. Solo i metodi dovrebbero essere disponibili esternamente (cioè al di fuori della tua classe). I dati dovrebbero essere nascosti. Potremmo fare un paragone con un telefono cellulare. Immagina che invece del solito telefono cellulare chiuso, ti venga dato un telefono con una custodia aperta, con tutti i tipi di fili sporgenti, circuiti, ecc. Ma il telefono funziona: se ti sforzi davvero e colpisci i circuiti, potresti anche essere in grado di effettuare una chiamata. Ma tu'
Getter e setter - 3
Invece, il produttore ti offre un'interfaccia: l'utente inserisce semplicemente le cifre corrette, preme il pulsante di chiamata verde e la chiamata ha inizio. Non le importa cosa succede all'interno con circuiti e fili, o come svolgono il loro lavoro. In questo esempio, l'azienda limita l'accesso agli "interni" del telefono (dati) ed espone solo un'interfaccia (metodi). Di conseguenza, l'utente ottiene ciò che voleva (la possibilità di effettuare una chiamata) e certamente non romperà nulla all'interno. Per rafforzare ciò che hai imparato, ti suggeriamo di guardare una lezione video dal nostro corso Java
Commenti
  • Popolari
  • Nuovi
  • Vecchi
Devi avere effettuato l'accesso per lasciare un commento
Questa pagina non ha ancora commenti