Sök…


Introduktion

Den här artikeln diskuterar bokstavar och uppsättare; det vanliga sättet att ge tillgång till data i Java-klasser.

Lägga till brev och bosättare

Inkapsling är ett grundläggande koncept i OOP. Det handlar om att slå in data och kod som en enda enhet. I det här fallet är det en bra praxis att förklara variablerna som private och sedan komma åt dem via Getters and Setters att se och / eller ändra dem.

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;
  }
}

Dessa privata variabler kan inte nås direkt utanför klassen. Därför skyddas de från obehörig åtkomst. Men om du vill visa eller ändra dem kan du använda Getters and Setters.

getXxx() returnerar det aktuella värdet för variabeln xxx , medan du kan ställa in värdet på variabeln xxx med setXxx() .

Metodernas namnkonvention är (i exempelvariabel heter variableName ):

  • Alla icke- boolean variabler

     getVariableName()   //Getter, The variable name should start with uppercase
     setVariableName(..) //Setter, The variable name should start with uppercase
    
  • boolean variabler

      isVariableName()     //Getter, The variable name should start with uppercase
      setVariableName(...) //Setter, The variable name should start with uppercase
    

Public Getters and Setters är en del av fastighetsdefinitionen av en Java Bean.

Använda en setter eller getter för att implementera en begränsning

Setters and Getters gör det möjligt för ett objekt att innehålla privata variabler som kan nås och ändras med begränsningar. Till exempel,

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;
    }
}

I denna Person finns det en enda variabel: name . Denna variabel kan nås med getName() och ändras med setName(String) , men för att ställa in ett namn krävs det nya namnet att ha en längd som är större än 2 tecken och inte är noll. Att använda en setter-metod snarare än att göra variabla name offentligt gör att andra kan ställa in name med vissa begränsningar. Detsamma kan tillämpas på getter-metoden:

public String getName(){
   if(name.length()>16)
      return "Name is too large!";
   else
      return name;
}

I den modifierade getName() -metoden ovan returneras name endast om dess längd är mindre än eller lika med 16. Annars returneras "Name is too large" . Detta tillåter programmeraren att skapa variabler som är tillgängliga och modifierbara men de vill, vilket hindrar klientklasser från att oönskat redigera variablerna.

Varför använda Getters and Setters?

Tänk på en grundklass som innehåller ett objekt med getters och setters i Java:

public class CountHolder {
  private int count = 0;

  public int getCount() { return count; }
  public void setCount(int c) { count = c; }
}

Vi har inte åtkomst till count eftersom den är privat. Men vi kan komma åt getCount() och setCount(int) eftersom de är offentliga. För vissa kan detta väcka frågan. varför introducera mellanhanden? Varför inte bara göra dem räkna offentliga?

public class CountHolder {
  public int count = 0;
}

I alla syften är dessa två exakt desamma, funktionsmässiga. Skillnaden mellan dem är utdragbarheten. Tänk på vad varje klass säger:

  • Först : "Jag har en metod som ger dig ett int värde och en metod som sätter det värdet till ett annat int ".
  • För det andra : "Jag har en int som du kan ställa in och få som du vill."

Dessa kanske låter liknande, men den första är faktiskt mycket mer bevakad i sin natur; den låter dig bara interagera med dess inre natur som den dikterar. Detta lämnar bollen i sin domstol; det får välja hur de interna interaktionerna ska uppstå. Den andra har exponerat sin interna implementering externt och är nu inte bara benägen för externa användare, utan, i fallet med ett API, åtagit sig att upprätthålla den implementeringen (eller på annat sätt släppa ett icke-bakåtkompatibelt API).

Låter oss överväga om vi vill synkronisera åtkomst till modifiering och åtkomst till räkningen. För det första är detta enkelt:

public class CountHolder {
  private int count = 0;

  public synchronized int getCount() { return count; }
  public synchronized void setCount(int c) { count = c; }
}

men i det andra exemplet är detta nu nästan omöjligt utan att gå igenom och ändra varje plats där count refereras. Värre är det, om detta är ett objekt som du tillhandahåller i ett bibliotek för att konsumeras av andra, har du inte ett sätt att utföra den modifieringen och tvingas göra det hårda valet som nämns ovan.

Så det väcker frågan; är offentliga variabler någonsin en bra sak (eller åtminstone inte ondska)?

Jag är osäker. Å ena sidan kan du se exempel på offentliga variabler som har stått tidens test (IE: out variabeln som refereras till i System.out ). Å andra sidan ger tillhandahållande av en offentlig variabel ingen fördel utanför extremt minimal omkostnad och potentiell minskning av ordlighet. Min riktlinje här skulle vara att om du planerar att offentliggöra en variabel bör du bedöma det mot dessa kriterier med extrem fördomar:

  1. Variabeln bör inte ha något tänkbart skäl att någonsin ändra i genomförandet. Detta är något som är extremt lätt att skruva upp (och även om du gör det rätt kan kraven ändras), varför getters / seters är den vanliga metoden. Om du ska ha en offentlig variabel måste detta verkligen tänkas igenom, särskilt om det släpps i ett bibliotek / ramverk / API.
  2. Variabeln måste refereras tillräckligt ofta för att de minimala vinsterna av att minska verbositeten garanterar det. Jag tror inte ens att omkostnaderna för att använda en metod kontra direktreferenser bör övervägas här. Det är alldeles för försumbart för vad jag konservativt uppskattar till 99,9% av ansökningarna.

Det finns förmodligen mer än jag inte har tänkt på mitt huvud. Om du någonsin är i tvivel, använd alltid getters / setters.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow