Hej! Låt oss ägna dagens lektion åt inkapsling och börja direkt med exempel :) Principer för inkapsling - 1Här har du en vanlig läskmaskin . Jag har en fråga till dig: hur fungerar det? Försök att ge ett detaljerat svar: var kommer koppen ifrån, hur hålls den inre temperaturen, var förvaras isen, hur vet maskinen vilken sirap som ska tillsättas etc.? Du har förmodligen inga svar på dessa frågor. Helt rätt, eftersom inte alla använder sådana maskiner. De är inte så populära nuförtiden. Låt oss försöka ge ett annat exempel. Något som du definitivt använder många gånger varje dag. Åh, här är en idé! Principer för inkapsling - 2Berätta för oss hur Googles sökmotorArbetar. Hur exakt söker den efter information relaterad till orden du anger? Varför rankas vissa resultat högt och andra inte? Även om du använder Google varje dag, är chansen stor att du inte vet. Men det spelar ingen roll. Du behöver inte veta detta. Du kan skriva in frågor i en sökmotor utan att tänka på hur det fungerar. Du kan köpa läsk från en maskin utan att veta hur det fungerar. Du kan köra bil utan att förstå hur en förbränningsmotor fungerar, och utan att kunna fysik alls, även på grundskolans nivå. Allt detta är möjligt tack vare en av huvudprinciperna för objektorienterad programmering: inkapsling. När du läser olika artiklar om objektorienterad programmering (OOP) måste du ha stött på det faktum att programmering involverar två vanliga begrepp: inkapsling och döljande . Och författare använder ordet "inkapsling" för att betyda en sak och sedan en annan. Vi kommer att utforska båda termerna så att du får en fullständig förståelse. Inom programmering är den ursprungliga innebörden av inkapsling buntning av data, tillsammans med de metoder som arbetar på dessa data, till en enda enhet (dvs. en "kapsel"). I Java är klassen enheten för inkapsling. En klass innehåller både data (fält) och metoder för att arbeta med dessa data.Principer för inkapsling - 3Detta kan tyckas vara det uppenbart korrekta tillvägagångssättet för dig, men i andra programmeringsparadigm är allt ordnat annorlunda. Till exempel, i funktionell programmering, är data strikt separerade från operationer på den. I OOP består program av kapslar, eller klasser, som består av både data och funktioner för att arbeta med den datan. Låt oss nu prata om att gömma oss . Hur kommer det sig att vi använder alla möjliga komplexa enheter utan att förstå hur de är organiserade eller hur de fungerar? Det är enkelt: deras skapare försåg oss med ett enkelt och bekvämt gränssnitt. På en läskmaskin är gränssnittet knapparna på panelen. Genom att trycka på en knapp väljer du koppstorlek. Trycker du på en annan väljer du smaken. En tredje är ansvarig för att lägga is. Och det är allt du behöver göra. Maskinens interna organisation spelar ingen roll. Det viktiga är att den är designad på ett sätt som kräver att användaren trycker på tre knappar för att få läsk . Detsamma gäller bilar. Det spelar ingen roll vad som händer inuti. Det viktiga är att när du trycker på höger pedal så rör sig bilen framåt, och när du trycker på vänster pedal saktar den ner. Det är det som gömmer sig. Alla programs "insida" är dolda för användaren. För användaren, denna överflödiga, onödiga information. Användaren behöver slutresultatet, inte den interna processen. Låt oss titta på Autoklassen som ett exempel:
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å här ser implementeringsdöljning ut i ett Java-program. Det är precis som i verkligheten: användaren förses med ett gränssnitt (metoder). Om användaren behöver en bil i ett program för att utföra en åtgärd, ringer han eller hon bara den önskade metoden. Det som händer i dessa metoder är överflödigt. Det viktiga är att allt fungerar som det ska. Här pratar vi om implementeringsdöljning . Förutom det har Java också datadöljande . Vi skrev om det i lektionen om getters och setters , men att granska konceptet kommer inte att skada. Till exempel har vi en Catklass:
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!");
   }


}
Du kanske minns problemet med den här klassen från förra lektionen? Om inte, låt oss komma ihåg det nu. Problemet är att dess data (fält) är öppna för alla - en annan programmerare kan enkelt skapa en namnlös katt med en vikt på 0 och en ålder på -1000 år:
public static void main(String[] args) {

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

}
Kanske kan du hålla ett öga på om någon av dina medarbetare har skapat objekt med ogiltigt tillstånd, men det vore mycket bättre att utesluta ens möjligheten att skapa sådana "ogiltiga objekt". Principer för inkapsling - 4Följande mekanismer hjälper oss att dölja data:
  1. åtkomstmodifierare ( privat , skyddat , standardpaket )
  2. getters och setters
Vi kan till exempel sätta en bock där för att se om någon försöker tilldela ett negativt tal till kattens ålder. Som vi sa tidigare menar författarna till olika artiklar om inkapsling ibland att kombinera data och metoder, eller dölja dem, eller båda (kombinera och dölja dem). Java har båda mekanismerna (detta är inte nödvändigtvis sant för andra OOP-språk), så den sista betydelsen är mest korrekt. Inkapsling ger oss flera viktiga fördelar:
  1. Kontroll över ett objekts korrekta tillstånd. Det fanns exempel på detta ovan. En setter och den privata modifieraren ser till att vårt program inte kommer att ha katter vars vikt är 0.

  2. Användarvänlighet genom ett gränssnitt. Endast metoder lämnas "exponerade" mot omvärlden. Det räcker med att ringa metoder för att få ett resultat – det finns absolut ingen anledning att fördjupa sig i detaljerna om hur de fungerar.

  3. Kodändringar påverkar inte användare. Vi gör alla ändringar i metoderna. Detta påverkar inte användaren av metoden: om rätt kod tidigare var "auto.gas()" för att använda gaspedalen kommer den att fortsätta att vara det. Det faktum att vi har ändrat något i gas()-metoden förblir osynligt för användaren: som tidigare får den som ringer helt enkelt det önskade resultatet.