CodeGym/Java blog/Tilfældig/Adgang modifikatorer i Java
John Squirrels
Niveau
San Francisco

Adgang modifikatorer i Java

Udgivet i gruppen
Hej! I dagens lektion vil vi stifte bekendtskab med begrebet adgangsmodifikatorer og overveje eksempler på, hvordan man arbejder med dem. At sige 'bliv bekendt' er selvfølgelig ikke helt rigtigt: du kender allerede de fleste af dem fra tidligere lektioner. For en sikkerheds skyld, lad os genopfriske vores hukommelse om det vigtigste punkt. Modifikatoradgang er oftest nøgleord, der regulerer adgangen til forskellige dele af din kode. Hvorfor 'oftest'? Fordi en af ​​dem er indstillet som standard uden brug af et nøgleord :) Java har fire adgangsmodifikatorer. Vi lister dem i rækkefølge fra mest restriktive til mest 'låsomme':
  • privat;
  • standard (pakke synlig);
  • beskyttet;
  • offentlig.
Lad os tage et kig på hver af dem og identificere, hvornår de kan være nyttige. Og vi giver eksempler :)

Den private modifikator

Adgangsmodifikatorer.  Privat, beskyttet, standard, offentlig - 2private er den mest restriktive adgangsmodifikator. Det begrænser synligheden af ​​data og metoder til inden for en enkelt klasse. Du kender denne modifikator fra lektionen om getters og settere. Kan du huske dette eksempel?
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 overvejede det i en tidligere lektion. Vi begik en alvorlig fejl her: Vi offentliggør vores data, hvilket gjorde det muligt for andre programmører at få direkte adgang til felterne og ændre deres værdier. Hvad mere er... disse værdier blev tildelt uden nogen kontrol. Det betyder, at vores program kunne skabe en kat ved navn "" med en alder på -1000 år og vægt på 0. For at løse dette problem brugte vi gettere og sættere og brugte også den private modifikator til at begrænse adgangen til dataene.
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;
   }
}
Grundlæggende er begrænsning af adgang til felter og implementering af gettere og sættere de mest almindelige eksempler på, hvor privatville blive brugt i virkeligt arbejde. Med andre ord er hovedformålet med denne modifikator at opnå indkapsling i et program. Dette gælder i øvrigt ikke kun for felter. Forestil dig, at dit program har en metode, der implementerer en MEGET kompleks funktionalitet. Hvad kan vi foreslå som eksempel? Lad os sige, at din readDataFromCollider()-metode accepterer en dataadresse som input, læser data fra Large Hadron Collider i byte-format, konverterer disse data til tekst, skriver dem til en fil og udskriver dem. Selv en beskrivelse af metoden ser skræmmende ud, for ikke at sige noget om koden :) For at gøre koden mere læsbar ville det være bedst ikke at skrive al metodens komplekse logik ét sted. I stedet bør vi opdele funktionaliteten i separate metoder. F.eks. readByteData()metoden er ansvarlig for at læse data, convertBytesToSymbols() metoden konverterer data læst fra kollideren til tekst, saveToFile() metoden gemmer den modtagne tekst til en fil, og printColliderData() metoden udskriver vores datafil. I sidste ende vil vores readDataFromCollider() metode være meget enklere:
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 vil huske fra lektionen om grænseflader, får brugeren kun adgang til den eksterne grænseflade. Og vores 4 metoder er ikke en del af det. De er hjælpemetoder: vi skabte dem for at forbedre kodens læsbarhed og for ikke at proppe fire forskellige opgaver ind i én metode. Du behøver ikke give brugeren adgang til disse metoder. Hvis brugere har adgang til convertBytesToSymbols() -metoden, når de arbejder med kollideren, vil de højst sandsynligt simpelthen blive forvirrede af metoden og spekulere på, hvad den er til for. Hvilke bytes konverteres? Hvor kom de fra? Hvorfor konvertere dem til tekst? Den logik, der udføres i denne metode, er ikke en del af den grænseflade, der er eksponeret for brugeren. Kun readDataFromCollider()metode er en del af grænsefladen. Så hvad gør vi med disse fire 'interne' metoder? Højre! Brug den private modifikator til at begrænse adgangen til dem. Dette giver dem mulighed for fredeligt at udføre deres arbejde i klassen uden at forvirre brugeren, som ikke behøver at kende logikken i hver enkelt metode.
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 beskyttede modifikator

Den næstmest restriktive modifikator er beskyttet . Adgangsmodifikatorer.  Privat, beskyttet, standard, offentlig - 3Felter og metoder markeret af den beskyttede adgangsmodifikator vil være synlige:
  • inden for alle klasser inkluderet i samme pakke som vores;
  • inden for alle klasser, der arver vores klasse.
I første omgang er det svært at forestille sig, hvornår dette kan være nødvendigt. Bliv ikke overrasket: Der er langt færre use cases for beskyttede end til private , og de er meget specifikke. Forestil dig, at vi har en AbstractSecretAgent abstrakt klasse, der repræsenterer en hemmelig agent i en eller anden efterretningstjeneste, samt en top_secret -pakke, der indeholder denne klasse og dens efterkommere. Konkrete klasser såsom FBISecretAgent , MI6SecretAgent , MossadSecretAgent osv. arver det. Inde i den abstrakte klasse ønsker vi at implementere en agenttæller. Det vil stige, når en ny agent oprettes et sted i programmet. pakke top_secret;
public abstract class AbstractSecretAgent {

   public static int agentCount = 0;
}
Men vores agenter er hemmelige! Det betyder, at de og ingen andre bør vide, hvor mange af dem der findes. Vi kan nemt tilføje den beskyttede modifikator til feltet agent_counter . Så kan forekomster af andre hemmelige agentklasser og andre klasser placeret i vores top_secret- pakke få sin værdi.
public abstract class AbstractSecretAgent {

   protected static int agent_counter = 0;
}
Og det er den slags specialiserede opgaver, der kræver den beskyttede modifikator :)

Pakkens synlige modifikator

Næste på listen er standardmodifikatoren , også kendt som pakkens synlige modifikator. Det er ikke angivet med et nøgleord, da Java anvender det som standard på alle felter og metoder. Hvis du skriver følgende i din kode:
int x = 10
x - variablen vil have denne pakke synlig adgang. Det er nemt at huske, hvad det gør. Grundlæggende er standard = beskyttet arv :) Ligesom den beskyttede modifikator er dens anvendelse begrænset. Oftest bruges standardadgang i en pakke, der har nogle hjælpeklasser, der ikke implementerer funktionaliteten af ​​alle de andre klasser i pakken. Lad os give et eksempel. Forestil dig, at vi har en 'service'-pakke. Den indeholder forskellige klasser, der arbejder med en database. For eksempel er der en UserService- klasse, der læser brugerdata fra databasen, en CarServiceklasse, der læser bildata fra den samme database, og andre klasser, som hver især arbejder med bestemte typer objekter og læser tilsvarende data fra databasen.
package services;

public class UserService {
}

package services;

public class CarService {
}
Men det ville være nemt for dataene i databasen at være i ét format, og vi har brug for det i et andet. Forestil dig, at brugernes fødselsdatoer i databasen er gemt som <TIMESTAMP WITH TIME ZONE>...
2014-04-04 20:32:59.390583+02
...og i stedet har vi brug for det enkleste objekt - en java.util.Date . For at løse dette problem kan vi inde i servicepakken oprette en speciel Mapper- klasse. Det vil være ansvarligt for at konvertere data fra databasen til vores velkendte Java-objekter. En simpel hjælperklasse. Vi erklærer normalt alle klasser som public class ClassName , men dette er ikke et krav. Vi kan erklære vores hjælperklasse blot som klasse Mapper . I dette tilfælde gør den stadig sit arbejde, men den er ikke synlig for nogen uden for servicepakken !
package services;

class Mapper {
}


package services;

public class CarService {

   Mapper mapper;
}
Og her er den grundlæggende begrundelse: hvorfor skulle nogen uden for en pakke have brug for at se en hjælperklasse, der kun fungerer med klasserne i den pakke?

Den offentlige modifikator

Og sidst, men ikke mindst, den offentlige modifikator! Du mødte denne modifikator på din første studiedag på CodeGym, første gang du kørte public static void main(String[] args) . Nu hvor du har studeret lektionen om grænseflader, er dens formål indlysende for dig :) Den offentligeAdgangsmodifikatorer.  Privat, beskyttet, standard, offentlig - 4 modifikator blev trods alt skabt for at give noget til brugerne. For eksempel dit programs grænseflade. Antag, at du har skrevet et oversætterprogram, der kan oversætte russisk tekst til engelsk. Du har oprettet en translate(String textInRussian) metode, der implementerer al den nødvendige logik. Du markerede denne metode med ordet offentlig , og nu er den en del af grænsefladen:
public class Translator {

   public String translate(String textInRussian) {

       // Translates text from Russian to English
   }
}
Du kan binde denne metode til knappen 'Oversæt' på skærmen, og du er færdig! Alle kan bruge det. De dele af koden, der er markeret med den offentlige modifikator, er beregnet til slutbrugeren. Som et eksempel fra det virkelige liv er privat for alle processer, der forekommer inde i et tv, men offentligt er for knapperne på fjernbetjeningen, der bruges til at styre tv'et. Hvad mere er, behøver brugeren ikke at vide, hvordan fjernsynet er bygget, eller hvordan det fungerer. Fjernbetjeningen er sættet af offentlige -metoder: on() , off() , nextChannel() , previousChannel() , increaseVolume() , reductionVolume() osv. For at styrke det, du har lært, foreslår vi, at du ser en videolektion fra vores Java-kursus
Kommentarer
  • Populær
  • Ny
  • Gammel
Du skal være logget ind for at skrive en kommentar
Denne side har ingen kommentarer endnu