CodeGym /Java-blogg /Tilfeldig /Getters og settere
John Squirrels
Nivå
San Francisco

Getters og settere

Publisert i gruppen
Hallo! I tidligere forelesninger har du allerede lært hvordan du erklærer dine egne fullverdige klasser med metoder og felt. I dagens leksjon skal vi snakke om Getters og Setters i Java. Dette er seriøs fremgang, godt gjort! Men nå må jeg fortelle deg en ubehagelig sannhet. Vi har ikke deklarert klassene våre riktig! Hvorfor? Ved første øyekast har følgende klasse ingen feil:

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!");
   }
}
Men det gjør det. Tenk deg at du sitter på jobb og skriv denne katteklassen for å representere katter. Og så drar du hjem. Mens du er borte, kommer en annen programmerer på jobb. Han lager sin egen hovedklasse , hvor han begynner å bruke Cat- klassen du skrev.

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Det spiller ingen rolle hvorfor han gjorde det og hvordan det skjedde (kanskje fyren er sliten eller har ikke fått nok søvn). Noe annet betyr noe: vår nåværende Cat- klasse gjør at felt kan tildeles helt vanvittige verdier. Som et resultat har programmet objekter med en ugyldig tilstand (som denne katten som er -1000 år gammel). Så hvilken feil gjorde vi da vi erklærte klassen vår? Vi avslørte klassens data. Feltene for navn, alder og vekt er offentlige. De kan nås hvor som helst i programmet: bare opprett et Cat- objekt, og enhver programmerer har direkte tilgang til dataene via prikken ( . )

Cat cat = new Cat();
cat.name = "";
Her får vi direkte tilgang til navnefeltet og angir verdien. Vi må på en eller annen måte beskytte dataene våre mot upassende ekstern interferens. Hva trenger vi for å gjøre det? Først må alle forekomstvariabler (felt) merkes med den private modifikatoren. Privat er den strengeste tilgangsmodifikatoren i Java. Når du har gjort dette, vil ikke feltene til Cat- klassen være tilgjengelige utenfor klassen.

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!
   }
}
Kompilatoren ser dette og genererer umiddelbart en feil. Nå er feltene på en måte beskyttet. Men det viser seg at vi har stengt tilgangen kanskje for tett: du kan ikke få en eksisterende katts vekt i programmet, selv om du trenger det. Dette er heller ikke et alternativ. Som det er, er klassen vår i hovedsak ubrukelig. Ideelt sett må vi tillate en slags begrenset tilgang:
  • Andre programmerere skal kunne lage Cat- objekter
  • De skal kunne lese data fra eksisterende objekter (for eksempel få navnet eller alderen til en eksisterende katt)
  • Det skal også være mulig å tildele feltverdier. Men når du gjør det, bør bare gyldige verdier tillates. Våre objekter bør beskyttes mot ugyldige verdier (f.eks. alder = -1000 osv.).
Det er en grei liste med krav! I virkeligheten oppnås alt dette enkelt med spesielle metoder som kalles getters og settere.
Getters og settere - 2
Disse navnene kommer fra "get" (dvs. "metode for å få verdien av et felt") og "sett" (dvs. "metode for å angi verdien av et felt"). La oss se hvordan de ser ut i vår Cat- klasse :

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;
   }
}
Som du ser ser de ganske enkle ut :) Navnene deres består ofte av "get"/"set" pluss navnet på det aktuelle feltet. For eksempel returnerer metoden getWeight() verdien av vektfeltet for objektet det kalles på. Slik ser det ut i et program:

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);
   }
}
Konsoll utgang:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
Nå kan en annen klasse ( Main ) få tilgang til Cat- feltene, men bare gjennom gettere. Merk at gettere har public access modifier, dvs. de er tilgjengelige fra hvor som helst i programmet. Men hva med å tildele verdier? Det er dette settermetoder er til for

public void setName(String name) {
   this.name = name;
}
Som du kan se, er de også enkle. Vi kaller setName() -metoden på et Cat- objekt, sender en streng som et argument, og strengen tilordnes objektets navnefelt.

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());
   }
}
Her bruker vi både gettere og settere. Først bruker vi en getter for å få og vise kattens opprinnelige navn. Deretter bruker vi en setter for å tildele et nytt navn ("Mr. Smudge"). Og så bruker vi getteren igjen for å få navnet (for å sjekke om det virkelig har endret seg). Konsoll utgang:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
Så hva er forskjellen? Vi kan fortsatt tilordne ugyldige verdier til felt selv om vi har settere:

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());
   }
}
Konsoll utgang:
Smudge's age: -1000 years
Forskjellen er at en setter er en fullverdig metode. Og i motsetning til et felt, lar en metode deg skrive verifikasjonslogikken som er nødvendig for å forhindre uakseptable verdier. Du kan for eksempel enkelt forhindre at et negativt tall blir tilordnet som en alder:

public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age can't be negative!");
   }
}
Og nå fungerer koden vår som den skal!

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());
   }
}
Konsoll utgang:
Error! Age can't be negative!
Smudge's age: 5 years
Inne i setteren opprettet vi en begrensning som beskyttet oss mot forsøket på å angi ugyldige data. Smudges alder ble ikke endret. Du bør alltid lage getters og settere. Selv om det ikke er noen begrensninger på hvilke verdier feltene dine kan ta, vil disse hjelpemetodene ikke skade. Tenk deg følgende situasjon: du og kollegene dine skriver et program sammen. Du oppretter en Cat- klasse med offentlige felt. Alle programmererne bruker dem slik de vil. Og så en vakker dag innser du: "Crap, før eller siden kan noen ved et uhell tildele vekten et negativt tall! Vi må lage settere og gjøre alle feltene private!" Du gjør nettopp det, og bryter umiddelbart all koden skrevet av kollegene dine. Tross alt, deKattefelt direkte.

cat.name = "Behemoth";
Og nå er feltene private og kompilatoren spyr ut en haug med feil!

cat.name = "Behemoth";//error! The Cat class's name field is private!
I dette tilfellet ville det være bedre å skjule feltene og lage getter og settere helt fra begynnelsen. Alle kollegene dine ville ha brukt dem. Og hvis du forsinket innså at du på en eller annen måte måtte begrense feltverdiene, kunne du bare ha skrevet sjekken inne i setteren. Og ingens kode ville bli ødelagt. Selvfølgelig, hvis du vil at tilgang til et felt bare skal være "skrivebeskyttet", kan du bare opprette en getter for det. Kun metoder skal være tilgjengelige eksternt (dvs. utenfor klassen din). Data bør skjules. Vi kan sammenligne med en mobiltelefon. Tenk deg at du i stedet for den vanlige vedlagte mobiltelefonen fikk en telefon med åpen veske, med alle mulige utstikkende ledninger, kretser osv. Men telefonen fungerer: hvis du prøver hardt og stikker i kretsene, kan du til og med bli kunne ringe. Men du'
Getters og settere - 3
I stedet gir produsenten deg et grensesnitt: brukeren skriver ganske enkelt inn de riktige sifrene, trykker på den grønne ringeknappen, og samtalen begynner. Hun bryr seg ikke om hva som skjer inne med kretsene og ledningene, eller hvordan de får jobben gjort. I dette eksemplet begrenser selskapet tilgangen til telefonens "innside" (data) og viser kun et grensesnitt (metoder). Som et resultat får brukeren det hun ønsket (muligheten til å ringe) og vil absolutt ikke ødelegge noe på innsiden. For å forsterke det du lærte, foreslår vi at du ser en videoleksjon fra vårt Java-kurs
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION