Hej! Lad os dedikere dagens lektion til indkapsling og begynde med det samme med eksempler :) Principper for indkapsling - 1Her har du en almindelig sodavandsmaskine . Jeg har et spørgsmål til dig: Hvordan fungerer det? Prøv at give et detaljeret svar: hvor kommer koppen fra, hvordan holdes den indre temperatur, hvor opbevares isen, hvordan ved maskinen hvilken sirup der skal tilsættes osv.? Du har sandsynligvis ikke svar på disse spørgsmål. Fair nok, da ikke alle bruger sådanne maskiner. De er ikke så populære i dag. Lad os prøve at give et andet eksempel. Noget du helt sikkert bruger mange gange hver dag. Åh, her er en idé! Principper for indkapsling - 2Fortæl os, hvordan Google-søgemaskinenarbejder. Hvordan søger den præcist efter information relateret til de ord, du indtaster? Hvorfor placeres visse resultater højt og andre ikke? Selvom du bruger Google hver dag, ved du det sandsynligvis ikke. Men det er lige meget. Du behøver ikke at vide dette. Du kan indtaste forespørgsler i en søgemaskine uden at tænke på, hvordan den fungerer. Du kan købe sodavand fra en maskine uden at vide, hvordan det virker. Du kan køre bil uden at forstå, hvordan en forbrændingsmotor fungerer, og uden at kunne fysik overhovedet, selv på folkeskoleniveau. Alt dette er muligt takket være et af hovedprincipperne for objektorienteret programmering: indkapsling. Når du læser forskellige artikler om objektorienteret programmering (OOP), skal du være stødt på, at programmering involverer to almindelige begreber: indkapsling og skjul . Og forfattere bruger ordet "indkapsling" til at betyde én ting og så en anden ting. Vi vil undersøge begge udtryk, så du opnår en fuldstændig forståelse. I programmering er den oprindelige betydning af indkapsling bundtning af data, sammen med de metoder, der opererer på disse data, i en enkelt enhed (dvs. en "kapsel"). I Java er klassen indkapslingsenheden. En klasse indeholder både data (felter) og metoder til at arbejde med disse data.Principper for indkapsling - 3Dette kan virke som den åbenlyst korrekte tilgang til dig, men i andre programmeringsparadigmer er alt arrangeret anderledes. For eksempel i funktionel programmering er data strengt adskilt fra operationer på dem. I OOP består programmer af kapsler eller klasser, som består af både data og funktioner til at arbejde med disse data. Lad os nu tale om at gemme sig . Hvordan kan det være, at vi bruger alle mulige komplekse enheder uden at forstå, hvordan de er organiseret, eller hvordan de fungerer? Det er enkelt: deres skabere gav os en enkel og praktisk grænseflade. På en sodavandsmaskine er grænsefladen knapperne på panelet. Ved at trykke på én knap vælger du kopstørrelsen. Ved at trykke på en anden vælger du smagen. En tredje er ansvarlig for at tilføje is. Og det er alt, du skal gøre. Den interne organisation af maskinen er ligegyldig. Det afgørende er, at det er designet på en måde, der kræver, at brugeren skal trykke på tre knapper for at få sodavand . Det samme er tilfældet med biler. Det er lige meget, hvad der foregår indeni. Det, der betyder noget, er, at når du trykker på højre pedal, bevæger bilen sig fremad, og når du trykker på venstre pedal, sænker den farten. Det er det, at skjule betyder. Hele et programs "inside" er skjult for brugeren. For brugeren, denne overflødige, unødvendige information. Brugeren har brug for slutresultatet, ikke den interne proces. Lad os se på Autoklassen som et eksempel:
public class Auto {

   public void go() {

       /* Some complicated things happen inside the car.
       As a result, it moves forward */
   }

   public void brake() {

       /* Some complicated things happen inside the car.
       As a result, it slows down. */
   }

   public static void main(String[] args) {

       Auto auto = new Auto();

       // From the user's perspective,

       // one pedal is pressed and the car accelerates.
       auto.gas();

       // The other is pressed, and the car slows down.
       auto.brake();
   }
}
Sådan ser implementeringsskjul ud i et Java-program. Det er ligesom i det virkelige liv: Brugeren er udstyret med en grænseflade (metoder). Hvis brugeren har brug for en bil i et program for at udføre en handling, kalder han eller hun blot den ønskede metode. Det, der sker inden for disse metoder, er overflødigt. Det afgørende er, at alt fungerer, som det skal. Her taler vi om implementeringsskjul . Udover det har Java også dataskjul . Vi skrev om det i lektionen om getters og setters , men at gennemgå konceptet vil ikke skade. For eksempel har vi en Catklasse:
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!");
   }


}
Måske husker du problemet med denne klasse fra sidste lektion? Hvis ikke, så lad os huske det nu. Problemet er, at dens data (felter) er åbne for alle - en anden programmør kan nemt skabe en navnløs kat med en vægt på 0 og en alder på -1000 år:
public static void main(String[] args) {

   Cat cat = new Cat();
   cat.name = "";
   cat.age = -1000;
   cat.weight = 0;

}
Måske kan du holde godt øje med, om en af ​​dine medarbejdere har oprettet objekter med ugyldig tilstand, men det ville være meget bedre at udelukke selv muligheden for at oprette sådanne "ugyldige objekter". Principper for indkapsling - 4Følgende mekanismer hjælper os med at skjule data:
  1. adgangsmodifikatorer ( privat , beskyttet , pakkestandard )
  2. gettere og sættere
For eksempel kan vi sætte et flueben der for at se, om nogen forsøger at tildele et negativt tal til kattens alder. Som vi sagde tidligere, mener forfatterne af forskellige artikler om indkapsling nogle gange at kombinere data og metoder eller skjule dem eller begge dele (kombinere og skjule dem). Java har begge mekanismer (dette er ikke nødvendigvis sandt for andre OOP-sprog), så den sidste betydning er mest korrekt. Indkapsling giver os flere vigtige fordele:
  1. Kontrol over den korrekte tilstand af et objekt. Det var der eksempler på ovenfor. En setter og den private modifikator sikrer, at vores program ikke vil have katte, hvis vægt er 0.

  2. Brugervenlighed gennem en grænseflade. Kun metoder efterlades "udsat" for omverdenen. Opkaldsmetoder er nok til at få et resultat - der er absolut ingen grund til at dykke ned i detaljerne om, hvordan de fungerer.

  3. Kodeændringer påvirker ikke brugere. Vi foretager enhver og alle ændringer inde i metoderne. Dette påvirker ikke brugeren af ​​metoden: hvis den rigtige kode tidligere var "auto.gas()" til at anvende gaspedalen, så vil den fortsætte med at være det. Det faktum, at vi har ændret noget inde i gas()-metoden, forbliver usynligt for brugeren: Som før modtager den, der ringer, blot det ønskede resultat.