CodeGym /Java blogg /Slumpmässig /Åtkomstmodifierare i Java
John Squirrels
Nivå
San Francisco

Åtkomstmodifierare i Java

Publicerad i gruppen
Hej! I dagens lektion kommer vi att bekanta oss med konceptet med åtkomstmodifierare och överväga exempel på hur man kan arbeta med dem. Naturligtvis är det inte helt rätt att säga "bekanta dig med": du är redan bekant med de flesta av dem från tidigare lektioner. För säkerhets skull, låt oss fräscha upp vårt minne av den viktigaste punkten. Modifierare åtkomst är oftast nyckelord som reglerar åtkomst till olika delar av din kod. Varför "oftast"? Eftersom en av dem är inställd som standard utan användning av ett nyckelord :) Java har fyra åtkomstmodifierare. Vi listar dem i ordning från mest restriktiva till mest "länksamma":
  • privat;
  • standard (paketet är synligt);
  • skyddad;
  • offentlig.
Låt oss ta en titt på var och en av dem och identifiera när de kan vara användbara. Och vi ska ge exempel :)

Den privata modifieraren

Åtkomstmodifierare.  Privat, skyddad, standard, offentlig - 2privat är den mest restriktiva åtkomstmodifieraren. Det begränsar synligheten för data och metoder till inom en enda klass. Du känner till denna modifierare från lektionen om getters och setters. Kommer du ihåg det här exemplet?

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!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
Vi övervägde det i en tidigare lektion. Vi gjorde ett allvarligt misstag här: Vi gör våra data offentliga, vilket gjorde det möjligt för andra programmerare att komma åt fälten direkt och ändra deras värden. Vad mer... dessa värden tilldelades utan några kontroller. Detta innebär att vårt program kunde skapa en katt som heter "" med en ålder på -1000 år och vikt 0. För att lösa detta problem använde vi getters och setters, och använde även den privata modifieraren för att begränsa åtkomsten till data.

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) {
       // input parameter check
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       // input parameter check
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       // input parameter check
       this.weight = weight;
   }
}
I grund och botten är begränsning av åtkomst till fält och implementering av getters och seters de vanligaste exemplen på hur privataskulle användas i verkligt arbete. Med andra ord, huvudsyftet med denna modifierare är att uppnå inkapsling i ett program. Detta gäller förresten inte bara för fält. Föreställ dig att ditt program har en metod som implementerar en MYCKET komplex funktionalitet. Vad kan vi föreslå som exempel? Låt oss säga att din readDataFromCollider()-metod accepterar en dataadress som indata, läser data från Large Hadron Collider i byteformat, konverterar denna data till text, skriver den till en fil och skriver ut den. Även en beskrivning av metoden ser skrämmande ut, för att inte tala om koden :) För att göra koden mer läsbar vore det bäst att inte skriva all metodens komplexa logik på ett ställe. Istället bör vi dela upp funktionaliteten i separata metoder. Till exempel, readByteData()metoden är ansvarig för att läsa data, metoden convertBytesToSymbols() omvandlar data som läses från kollideraren till text, metoden saveToFile() sparar den mottagna texten till en fil och metoden printColliderData() skriver ut vår datafil. I slutändan kommer vår readDataFromCollider() -metod att vara mycket enklare:

public class ColliderUtil {

   public void readDataFromCollider(Path pathToData) {
       byte[] colliderData = readByteData(pathToData);
       String[] textData = convertBytesToSymbols(colliderData);
       File fileWithData = saveToFile(textData);
       printColliderData(fileWithData);
   }

   public byte[] readByteData(Path pathToData) {

       // Reads data in bytes
   }

   public String[] convertBytesToSymbols(byte[] colliderDataInBytes) {

       // Converts bytes to characters
   }

   public File saveToFile(String[] colliderData) {

       // Saves read data to a file
   }

   public void printColliderData(File fileWithColliderData) {

       // Prints data from the file
   }
}
Men som du kommer ihåg från lektionen om gränssnitt får användaren bara tillgång till det externa gränssnittet. Och våra fyra metoder är inte en del av det. De är hjälpmetoder: vi skapade dem för att förbättra kodens läsbarhet och för att inte klämma ihop fyra olika uppgifter i en metod. Du behöver inte ge användaren tillgång till dessa metoder. Om användare har tillgång till metoden convertBytesToSymbols() när de arbetar med kollideraren, kommer de troligen helt enkelt att bli förvirrade av metoden och undra vad den är till för. Vilka byte konverteras? Var kom de ifrån? Varför konvertera dem till text? Logiken som exekveras i denna metod är inte en del av gränssnittet som exponeras för användaren. Endast readDataFromCollider()metod är en del av gränssnittet. Så vad gör vi med dessa fyra "interna" metoder? Höger! Använd den privata modifieraren för att begränsa åtkomsten till dem. Genom att göra detta kan de lugnt utföra sitt arbete i klassen utan att förvirra användaren, som inte behöver känna till logiken i varje enskild metod.

public class ColliderUtil {

   public void readDataFromCollider(Path pathToData) {
       byte[] colliderData = readByteData(pathToData);
       String[] textData = convertBytesToSymbols(colliderData);
       File fileWithData = saveToFile(textData);
       printColliderData(fileWithData);
   }

   private byte[] readByteData(Path pathToData) {
       // Reads data in bytes
   }

   private String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
       // Converts bytes to characters
   }

   private File saveToFile(String[] colliderData) {
       // Saves read data to a file
   }

   private void printColliderData(File fileWithColliderData) {
       // Prints data from the file
   }
}

Den skyddade modifieraren

Den näst mest restriktiva modifieraren är skyddad . Åtkomstmodifierare.  Privat, skyddad, standard, offentlig - 3Fält och metoder markerade av den skyddade åtkomstmodifieraren kommer att vara synliga:
  • inom alla klasser som ingår i samma paket som vårt;
  • inom alla klasser som ärver vår klass.
Till en början är det svårt att föreställa sig när detta kan behövas. Bli inte förvånad: det finns mycket färre användningsfall för skyddade än för privata , och de är mycket specifika. Föreställ dig att vi har en AbstractSecretAgent abstrakt klass som representerar en hemlig agent i någon underrättelsetjänst, samt ett top_secret- paket som innehåller denna klass och dess ättlingar. Konkreta klasser som FBISecretAgent , MI6SecretAgent , MossadSecretAgent etc. ärver det. Inuti den abstrakta klassen vill vi implementera en agenträknare. Den kommer att öka när en ny agent skapas någonstans i programmet. paketet top_secret;

public abstract class AbstractSecretAgent {

   public static int agentCount = 0;
}
Men våra agenter är hemliga! Det betyder att de och ingen annan ska veta hur många av dem som finns. Vi kan enkelt lägga till den skyddade modifieraren i fältet agent_counter . Då kan instanser av andra hemliga agentklasser och andra klasser som finns i vårt top_secret -paket få sitt värde.

public abstract class AbstractSecretAgent {

   protected static int agent_counter = 0;
}
Och det är den sortens specialiserade uppgift som kräver den skyddade modifieraren :)

Paketets synliga modifierare

Nästa på listan är standardmodifieraren , även känd som paketets synliga modifierare. Det indikeras inte av ett nyckelord, eftersom Java tillämpar det som standard på alla fält och metoder. Om du skriver följande i din kod:

int x = 10
variabeln x kommer att ha det här paketet synlig åtkomst. Det är lätt att komma ihåg vad den gör. I grund och botten är standard = skyddat arv :) Liksom den skyddade modifieraren är dess tillämpning begränsad. Oftast används standardåtkomst i ett paket som har några verktygsklasser som inte implementerar funktionaliteten för alla andra klasser i paketet. Låt oss ge ett exempel. Föreställ dig att vi har ett "servicepaket". Den innehåller olika klasser som fungerar med en databas. Till exempel finns det en UserService- klass som läser användardata från databasen, en CarServiceklass som läser bildata från samma databas, och andra klasser, som var och en arbetar med specifika typer av objekt och läser motsvarande data från databasen.

package services;

public class UserService {
}

package services;

public class CarService {
}
Men det skulle vara lätt för datan i databasen att vara i ett format och vi behöver det i ett annat. Föreställ dig att användarnas födelsedatum i databasen lagras som <TIMESTAMP WITH TIME ZONE>...

2014-04-04 20:32:59.390583+02
...och istället behöver vi det enklaste objektet — ett java.util.Date . För att lösa detta problem, inuti tjänstepaketet , kan vi skapa en speciell Mapper- klass. Den kommer att ansvara för att konvertera data från databasen till våra välbekanta Java-objekt. En enkel hjälparklass. Vi brukar deklarera alla klasser som public class ClassName , men detta är inte ett krav. Vi kan deklarera vår hjälparklass helt enkelt som klasskartare . I det här fallet gör den fortfarande sitt jobb, men den är inte synlig för någon utanför tjänstepaketet !

package services;

class Mapper {
}


package services;

public class CarService {

   Mapper mapper;
}
Och här är det grundläggande resonemanget: varför skulle någon utanför ett paket behöva se en hjälpklass som bara fungerar med klasserna i det paketet?

Den offentliga modifieraren

Och sist men inte minst, den offentliga modifieraren! Du träffade den här modifieraren på din första studiedag på CodeGym första gången du körde public static void main(String[] args) . Åtkomstmodifierare.  Privat, skyddad, standard, offentlig - 4Nu när du har studerat lektionen om gränssnitt är dess syfte uppenbart för dig :) Trots allt skapades den offentliga modifieraren för att ge något till användarna. Till exempel ditt programs gränssnitt. Anta att du har skrivit ett översättningsprogram som kan översätta rysk text till engelska. Du skapade en translate(String textInRussian) metod som implementerar all nödvändig logik. Du markerade den här metoden med ordet offentlig , och nu är den en del av gränssnittet:

public class Translator {

   public String translate(String textInRussian) {

       // Translates text from Russian to English
   }
}
Du kan binda denna metod till "Översätt"-knappen på skärmen och du är klar! Vem som helst kan använda den. De delar av koden som är markerade med den offentliga modifieraren är avsedda för slutanvändaren. Som ett exempel i verkligheten är privat för alla processer som sker inuti en TV, men offentlig är för knapparna på fjärrkontrollen som används för att hantera TV:n. Dessutom behöver användaren inte veta hur TV:n är byggd eller hur den fungerar. Fjärrkontrollen är uppsättningen av offentliga -metoder: on() , off() , nextChannel() , previousChannel() , increaseVolume() , reductionVolume() etc. För att förstärka det du lärde dig föreslår vi att du tittar på en videolektion från vår Java-kurs
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION