John Squirrels
Nivå
San Francisco

OOP-principer

Publicerad i gruppen
Hej! I dagens lektion kommer vi att prata om principerna för objektorienterad programmering. Har du någonsin undrat varför Java är designat precis som det är? Jag menar, man deklarerar klasser och skapar objekt utifrån klasser, klasser har metoder etc. Men varför är språket uppbyggt så att program består av klasser och objekt, och inte något annat? Varför uppfanns begreppet "objekt" och sattes på spetsen? Är alla språk utformade på detta sätt? Om inte, vilka fördelar ger det Java? Som du kan se finns det många frågor :) Låt oss försöka svara på var och en av dem i dagens lektion.

Vad är objektorienterad programmering (OOP)?

Naturligtvis består Java inte av objekt och klasser bara för skojs skull. De är inte ett infall av Javas skapare, och inte ens deras uppfinning. Det finns många andra språk baserade på objekt. Det första sådana språket kallades "Simula". Den uppfanns redan på 1960-talet i Norge. Dessutom dök begreppen "klass" och "metod" upp i Simula. Enligt standarderna för mjukvaruutveckling verkar "Simula" som ett uråldrigt språk, men vem som helst kan se dess "familjelikhet" med Java. Principer för objektorienterad programmering - 1Du kan förmodligen enkelt läsa koden skriven på detta språk och förklara i stora drag vad den gör :)
Begin
	Class Rectangle (Width, Height); Real Width, Height;

	 Begin
	    Real Area, Perimeter;

	    Procedure Update;
	    Begin
	      Area := Width * Height;
              OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
	      Perimeter := 2*(Width + Height);
              OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
	    End of Update;

	    Update;
	    OutText("Rectangle created: "); OutFix(Width,2,6);
	    OutFix(Height,2,6); OutImage;
	 End of Rectangle;

       Rectangle Class ColouredRectangle (Color); Text Color;

	Begin
	    OutText("ColouredRectangle created, color = "); OutText(Color);
	    OutImage;
        End of ColouredRectangle;


      	 Ref(Rectangle) Cr;
	 Cr :- New ColouredRectangle(10, 20, "Green");
End;
Denna kodprovskod togs från "Simula - 50 years of OOP" av Weekly-geekly. Som du kan se skiljer sig Java inte så mycket från sin farfar :) Detta beror på att Simulas utseende markerade födelsen av ett nytt koncept: objektorienterad programmering. Wikipedia definierar OOP så här: "Object-Oriented Programming (OOP) är ett programmeringsparadigm baserat på konceptet "objekt", som kan innehålla data, i form av fält (ofta kända som attribut), och kod, i formen av procedurer (ofta kända som metoder)." Enligt mig är detta en riktigt bra definition. Det var inte länge sedan du började lära dig Java, men den här definitionen innehåller förmodligen inga ord du inte känner till :) Idag är OOP den vanligaste programmeringsmetoden. Förutom Java, OOP-principer används på många populära språk som du kanske har hört talas om. Till exempel, C++ (används aktivt i spelutveckling), Objective-C och Swift (används för att skriva program för Apple-enheter), Python (mest populärt inom maskininlärning), PHP (ett av de mest populära webbutvecklingsspråken), JavaScript ( det är lättare att säga vad det inte används till) och många andra. Så, vad är principerna för OOP ändå? Vi kommer att berätta i detalj. vad är principerna för OOP ändå? Vi kommer att berätta i detalj. vad är principerna för OOP ändå? Vi kommer att berätta i detalj.

OOP-principer

Dessa är grunden för stiftelsen. De 4 huvuddragen som tillsammans bildar det objektorienterade programmeringsparadigmet. Att förstå dem är viktigt för att bli en framgångsrik programmerare.

Princip 1. Arv

Goda nyheter: du känner redan till några av principerna för OOP! :) Vi har redan stött på arv ett par gånger på lektionerna, och vi lyckades använda det. Arv är en mekanism som låter dig beskriva en ny klass baserat på en befintlig (förälder) klass. Genom att göra det lånar den nya klassen egenskaperna och funktionerna för den överordnade klassen. Vad är arv till för och vilka fördelar ger det? Framför allt återanvändning av kod. Fälten och metoderna som deklareras i överordnade klasser kan användas i underordnade klasser. Om alla typer av bilar har 10 vanliga fält och 5 identiska metoder behöver du bara flytta dem till Autoföräldraklass. Du kan använda dem i efterkommande klasser utan problem. Solida fördelar: både kvantitativ (mindre kod) och, som ett resultat, kvalitativ (klasser blir mycket enklare). Dessutom är arv väldigt flexibelt - du kan lägga till separata skrivfunktioner som ättlingarna saknar (vissa fält eller beteenden som är specifika för en viss klass). I allmänhet, som i det verkliga livet, är vi alla lite lika våra föräldrar, men också på något sätt olika dem :)

Princip 2. Abstraktion

Detta är en mycket enkel princip. Abstraktion betyder att identifiera de viktigaste, mest betydelsefulla egenskaperna hos något, samtidigt som man kasserar allt mindre och obetydligt. Inget behov av att uppfinna hjulet på nytt. Låt oss komma ihåg ett exempel från en gammal lektion om klasser. Anta att vi skapar ett arkivsystem för företagets anställda. För att skapa "anställda"-objekt har vi skrivit en Employee- klass. Vilka egenskaper är viktiga för att beskriva dem i företagets registersystem? Namn, födelsedatum, SSN och anställds ID. Men det är osannolikt att vi kommer att behöva medarbetarens längd, ögonfärg eller hårfärg för denna typ av rekord. Bolaget har inget behov av sådan information om en anställd. Så i klassen Employee deklarerar vi följande variabler:, int age , int socialSecurityNumber och int employeeId . Och vi abstraherar bort onödig information som ögonfärg. Men om vi gör ett arkiveringssystem för en modellbyrå förändras situationen dramatiskt. En modells längd, ögonfärg och hårfärg är viktiga egenskaper, men hennes SSN är absolut irrelevant för oss. Så i klassen Model skapar vi följande variabler: String höjd , String hair , String eyes .

Princip 3. Inkapsling

Vi har redan stött på det här. I Java innebär inkapsling att man begränsar möjligheten att läsa och ändra data. Som du kan se är termen baserad på ordet "kapsel". Vi kommer att använda en "kapsel" för att dölja vissa viktiga data som vi inte vill att andra ska ändra. Här är ett enkelt exempel från det verkliga livet. Du har ett förnamn och ett efternamn. Alla dina vänner känner dem. Men de har inte möjlighet att ändra ditt för- eller efternamn. Vi kan säga att processen för att göra det är "inkapslad" av domstolssystemet: du kan bara ändra ditt efternamn genom domstolstjänstemannen, och bara du kan göra det. Andra "användare" har "skrivskyddad" tillgång till ditt för- och efternamn :) Ett annat illustrativt exempel är kontanter som förvaras hemma. Att lämna det synligt mitt i rummet är inte en bra idé. Varje "användare" (person som kommer till ditt hus) kommer att kunna ändra summan av dina pengar, dvs de kan ta dina pengar. Det skulle vara bättre att kapsla in det i ett kassaskåp. Då skulle åtkomst endast vara tillgänglig för dig och endast genom att använda en speciell kod. Uppenbara exempel på inkapsling som du redan har arbetat med är åtkomstmodifierare (privata, offentliga, etc.), samt sättare och getters. Om du inte kapslar inKattklassens åldersfält , då kan vem som helst skriva :
Cat.age = -1000;
Inkapslingsmekanismen låter oss skydda åldersfältet med en sättermetod, där vi kan säkerställa att ålder inte kan sättas till ett negativt tal.

Princip 4. Polymorfism

Polymorfism är förmågan att arbeta med flera typer som om de vore samma typ. Dessutom kommer objektens beteende att vara olika beroende på deras typ. Låter det komplicerat? Låt oss fatta det nu. Ta det enklaste exemplet: djur. Skapa en Animal- klass med en enda speak() -metod och två underklasser – Cat och Dog .
public class Animal {

   public void speak() {

       System.out.println("Hello!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println ("Woof-woof!");
   }
}

public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}
Nu ska vi försöka deklarera en djurreferensvariabel och tilldela ett hundobjekt till den.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.speak();
   }
}
Vilken metod tror du kommer att heta? Animal.speak() eller Dog.speak() ? Metoden i klassen Hund kommer att heta: Woof-woof! Vi skapade en djurreferens , men objektet beter sig som en hund . Om det behövs kan det bete sig som en katt, häst eller något annat djur. Det viktiga är att tilldela en specifik underklass till den allmänna djurreferensvariabeln . Detta är vettigt, eftersom alla hundar är djur. Det var vad vi hade i åtanke när vi sa "objektens beteende kommer att vara olika beroende på deras typ." Om vi ​​skapade ett Cat- objekt...
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.speak();
}
metoden speak () skulle visa "Mjau!" Men vad menar vi med "förmågan att arbeta med flera typer som om de vore samma typ"? Detta är också ganska okomplicerat. Låt oss föreställa oss att vi skapar en frisersalong för djur. Vår frisörsalong ska kunna ge alla djur en trimning, så vi skapar en trim() -metod med en Animal- parameter (djuret som klipps).
public class AnimalBarbershop {

   public void trim(Animal animal) {

       System.out.println("The haircut is done!");
   }
}
Och nu kan vi skicka katt- och hundobjekt till trim()- metoden!
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.trim(cat);
   barbershop.trim(dog);
}
Och här är det tydliga exemplet: AnimalBarbershop -klassen arbetar med katt- och hundtyperna som om de vore samma typ. Samtidigt har katt och hund olika beteenden: de talar olika.

Varför behöver vi OOP?

Varför uppstod OOP någonsin som ett nytt programmeringskoncept? Programmerare hade fungerande verktyg, såsom procedurspråk. Vad fick dem att uppfinna något i grunden nytt? Framför allt komplexiteten i de uppgifter som de stod inför. Om programmerarens uppgift för 60 år sedan var något i stil med att "utvärdera ett matematiskt uttryck", kan det nu vara något i stil med "implementera 7 olika avslutningar för spelet STALKER, beroende på kombinationer av spelarens beslut fattade vid punkterna A, B, C, DE , och F i spelet." Som du kan se har uppgifterna uppenbarligen blivit mer komplicerade under de senaste decennierna. Och som ett resultat har datatyperna blivit mer komplicerade. Detta är ytterligare en anledning till att OOP dök upp. Ett matematiskt uttryck kan enkelt utvärderas med vanliga primitiver. Här behövs inga föremål. Men uppgiften med spelsluten skulle vara svår att ens beskriva utan att använda anpassade klasser. Som sagt, det är ganska enkelt att beskriva det med hjälp av klasser och objekt. Självklart behöver vi flera klasser: Game, Stalker, Ending, PlayerDecision, GameEvent, och så vidare. Med andra ord, även utan att börja lösa problemet kan vi enkelt "skissa fram" en lösning i vårt huvud. Den ökande komplexiteten i uppgifterna tvingade programmerare att dela upp dem i delar. Men detta var inte så lätt att göra i procedurprogrammering. Och ganska ofta var ett program som ett träd med massor av grenar som representerade alla möjliga avrättningsvägar. Beroende på vissa förhållanden kördes en eller annan gren av programmet. För små program var detta bekvämt, men det var väldigt svårt att dela upp ett stort problem i delar. Detta var ännu en anledning till uppkomsten av OOP. Detta paradigm gav programmerare möjligheten att dela upp ett program i ett gäng "moduler" (klasser), som var och en gör sin egen del av arbetet. Genom att interagera med varandra utför alla objekt arbetet med vårt program. Dessutom kan vi återanvända vår kod någon annanstans i programmet, vilket också sparar mycket tid.
Kommentarer
  • Populär
  • Ny
  • Gammal
Du måste vara inloggad för att lämna en kommentar
Den här sidan har inga kommentarer än