CodeGym /Java Blog /Willekeurig /OOP-principes
John Squirrels
Niveau 41
San Francisco

OOP-principes

Gepubliceerd in de groep Willekeurig
Hoi! In de les van vandaag zullen we het hebben over de principes van objectgeoriënteerd programmeren. Heb je je ooit afgevraagd waarom Java precies is ontworpen zoals het is? Ik bedoel, je declareert klassen en maakt objecten op basis van klassen, klassen hebben methoden, enz. Maar waarom is de taal zo gestructureerd dat programma's uit klassen en objecten bestaan, en niet uit iets anders? Waarom werd het concept van een "object" uitgevonden en op de voorgrond geplaatst? Zijn alle talen op deze manier ontworpen? Zo nee, welke voordelen biedt het Java? Zoals je kunt zien, zijn er veel vragen :) Laten we proberen ze allemaal in de les van vandaag te beantwoorden.

Wat is objectgeoriënteerd programmeren (OOP)?

Natuurlijk bestaat Java niet voor de lol uit objecten en klassen. Ze zijn geen gril van de makers van Java, en zelfs niet hun uitvinding. Er zijn veel andere talen gebaseerd op objecten. De eerste dergelijke taal heette "Simula". Het werd uitgevonden in de jaren zestig in Noorwegen. Bovendien verschenen de concepten van een "klasse" en "methode" in Simula. Volgens de normen van softwareontwikkeling lijkt "Simula" een oude taal, maar iedereen kan de "familiegelijkenis" met Java zien. Principes van objectgeoriënteerd programmeren - 1Je kunt de code die in deze taal is geschreven waarschijnlijk gemakkelijk lezen en in grote lijnen uitleggen wat het doet :)

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;
Deze codevoorbeeldcode is overgenomen uit "Simula - 50 jaar OOP" door Weekly-geekly. Zoals je kunt zien, verschilt Java niet zo veel van zijn grootvader :) Dit komt doordat de verschijning van Simula de geboorte markeerde van een nieuw concept: objectgeoriënteerd programmeren. Wikipedia definieert OOP als volgt: "Object-Oriented Programming (OOP) is een programmeerparadigma gebaseerd op het concept van "objecten", die gegevens kunnen bevatten, in de vorm van velden (vaak bekend als attributen), en code, in de vorm van procedures (vaak bekend als methoden)." Naar mijn mening is dit een heel goede definitie. Het is nog niet zo lang geleden dat u Java begon te leren, maar deze definitie bevat waarschijnlijk geen woorden die u niet kent :) Tegenwoordig is OOP de meest gebruikelijke programmeermethode. Naast java, OOP-principes worden gebruikt in veel populaire talen waarvan je misschien wel eens hebt gehoord. Bijvoorbeeld C++ (actief gebruikt in game-ontwikkeling), Objective-C en Swift (gebruikt om programma's voor Apple-apparaten te schrijven), Python (meest populair in machine learning), PHP (een van de meest populaire webontwikkelingstalen), JavaScript ( het is gemakkelijker om te zeggen waarvoor het niet wordt gebruikt) en vele andere. Dus, wat zijn eigenlijk de principes van OOP? We vertellen het je in detail. wat zijn eigenlijk de principes van OOP? We vertellen het je in detail. wat zijn eigenlijk de principes van OOP? We vertellen het je in detail.

OOP-principes

Dit zijn de fundamenten van het fundament. De 4 belangrijkste kenmerken die samen het objectgeoriënteerde programmeerparadigma vormen. Het begrijpen ervan is essentieel om een ​​succesvolle programmeur te worden.

Principe 1. Overerving

Goed nieuws: je kent al enkele principes van OOP! :) We zijn al een paar keer overerving tegengekomen in lessen, en we zijn erin geslaagd om het te gebruiken. Overerving is een mechanisme waarmee u een nieuwe klasse kunt beschrijven op basis van een bestaande (bovenliggende) klasse. Daarbij leent de nieuwe klasse de eigenschappen en functionaliteit van de bovenliggende klasse. Waar is overerving voor en welke voordelen biedt het? Bovenal hergebruik van code. De velden en methoden die in bovenliggende klassen zijn gedeclareerd, kunnen worden gebruikt in onderliggende klassen. Als alle soorten auto's 10 gemeenschappelijke velden en 5 identieke methoden hebben, hoef je ze alleen maar naar de Auto te verplaatsenouder klasse. Je kunt ze zonder problemen gebruiken in afstammelingenklassen. Solide voordelen: zowel kwantitatief (minder code) als daardoor kwalitatief (klassen worden veel eenvoudiger). Bovendien is overerving zeer flexibel: u kunt afzonderlijke schrijffunctionaliteit toevoegen die de afstammelingen missen (sommige velden of gedragingen die specifiek zijn voor een bepaalde klasse). Over het algemeen lijken we allemaal, net als in het echte leven, enigszins op onze ouders, maar verschillen we ook op de een of andere manier van hen :)

Principe 2. Abstractie

Dit is een heel eenvoudig principe. Abstractie betekent het identificeren van de belangrijkste, meest significante kenmerken van iets, terwijl tegelijkertijd iets kleins en onbeduidends wordt weggegooid. Het is niet nodig om het wiel opnieuw uit te vinden. Laten we ons een voorbeeld herinneren uit een oude les over klassen. Stel dat we een archiefsysteem maken voor werknemers van het bedrijf. Om "employee"-objecten te maken, hebben we een Employee- klasse geschreven. Welke kenmerken zijn belangrijk om ze te beschrijven in het bedrijfsarchief? Naam, geboortedatum, SSN en werknemers-ID. Maar het is onwaarschijnlijk dat we de lengte, oogkleur of haarkleur van de werknemer nodig hebben voor dit type dossier. Het bedrijf heeft dergelijke informatie over een werknemer niet nodig. In de klasse Employee declareren we dus de volgende variabelen:, int age , int socialSecurityNumber en int employeeId . En we abstraheren onnodige informatie zoals oogkleur. Als we echter een archiefsysteem maken voor een modellenbureau, verandert de situatie drastisch. De lengte, oogkleur en haarkleur van een model zijn belangrijke kenmerken, maar haar SSN is absoluut niet relevant voor ons. In de klasse Model maken we dus de volgende variabelen: String height , String hair , String eyes .

Principe 3. Inkapseling

We zijn hier al tegenaan gelopen. In Java betekent inkapseling het beperken van de mogelijkheid om gegevens te lezen en te wijzigen. Zoals u kunt zien, is de term gebaseerd op het woord "capsule". We gebruiken een "capsule" om enkele belangrijke gegevens te verbergen waarvan we niet willen dat anderen ze wijzigen. Hier is een eenvoudig voorbeeld uit het echte leven. Je hebt een voornaam en een achternaam. Al je vrienden kennen ze. Maar ze hebben niet de mogelijkheid om uw voor- of achternaam te wijzigen. We zouden kunnen zeggen dat het proces om dat te doen is "ingekapseld" door het rechtssysteem: u kunt uw achternaam alleen wijzigen via de griffier, en alleen u kunt het doen. Andere "gebruikers" hebben "alleen-lezen" toegang tot uw voor- en achternaam :) Een ander illustratief voorbeeld is contant geld dat thuis wordt bewaard. Het midden in je kamer in het zicht laten staan ​​is geen goed idee. Elke "gebruiker" (persoon die bij u thuis komt) kan het bedrag van uw geld wijzigen, dwz ze kunnen uw geld aannemen. Het zou beter zijn om het in een kluis in te kapselen. Dan is toegang alleen voor jou beschikbaar en alleen door een speciale code te gebruiken. Voor de hand liggende voorbeelden van inkapseling waarmee u al hebt gewerkt, zijn toegangsmodificatoren (privé, openbaar, enz.), evenals setters en getters. Als je deHet leeftijdsveld van de kattenklasse , dan kan iedereen schrijven:

Cat.age = -1000;
Het inkapselingsmechanisme stelt ons in staat het leeftijdsveld te beschermen met een settermethode, waarbij we ervoor kunnen zorgen dat leeftijd niet op een negatief getal kan worden ingesteld.

Principe 4. Polymorfisme

Polymorfisme is het vermogen om met verschillende typen te werken alsof ze van hetzelfde type zijn. Bovendien zal het gedrag van de objecten verschillen, afhankelijk van hun type. Klinkt dat ingewikkeld? Laten we het nu begrijpen. Neem het eenvoudigste voorbeeld: dieren. Maak een Animal- klasse met een enkele speak()- methode en twee subklassen — Cat en 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 gaan we proberen een Animal- referentievariabele te declareren en er een Dog- object aan toe te wijzen.

public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.speak();
   }
}
Welke methode denk je dat zal worden genoemd? Animal.speak() of Dog.speak() ? De methode in de klasse Dog zal worden genoemd: Woef-woef! We hebben een Animal- referentie gemaakt, maar het object gedraagt ​​zich als een Dog . Indien nodig kan het zich gedragen als een kat, paard of een ander dier. Het belangrijkste is om een ​​specifieke subklasse toe te wijzen aan de algemene referentievariabele Animal . Logisch, want alle honden zijn dieren. Dat is wat we in gedachten hadden toen we zeiden: "Het gedrag van de objecten zal verschillen, afhankelijk van hun type." Als we een Cat- object zouden maken...

public static void main(String[] args) {

   Animal cat = new Cat();
   cat.speak();
}
de speak() methode zou "Miauw!" Maar wat bedoelen we met 'het vermogen om met meerdere typen te werken alsof ze van hetzelfde type zijn'? Dit is ook vrij eenvoudig. Laten we ons voorstellen dat we een kapperszaak voor dieren creëren. Onze kapperszaak zou elk dier een trimbeurt moeten kunnen geven, dus maken we een trim() methode met een Animal parameter (het dier wordt geknipt).

public class AnimalBarbershop {

   public void trim(Animal animal) {

       System.out.println("The haircut is done!"); 
   }
}
En nu kunnen we Cat- en Dog -objecten doorgeven aan de trim()- methode!

public static void main(String[] args) {

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

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.trim(cat);
   barbershop.trim(dog);
}
En hier is het duidelijke voorbeeld: de klasse AnimalBarbershop werkt met de typen kat en hond alsof ze van hetzelfde type zijn. Tegelijkertijd vertonen Kat en Hond ander gedrag: ze spreken allemaal anders.

Waarom hebben we OOP nodig?

Waarom is OOP ooit ontstaan ​​als een nieuw programmeerconcept? Programmeurs hadden functionerende tools, zoals proceduretalen. Wat bracht hen ertoe iets fundamenteel nieuws uit te vinden? Vooral de complexiteit van de taken waarmee ze te maken kregen. Als 60 jaar geleden de taak van de programmeur zoiets was als "een wiskundige uitdrukking evalueren", zou het nu zoiets kunnen zijn als "implementeer 7 verschillende eindes voor het spel STALKER, afhankelijk van combinaties van de beslissingen van de speler genomen op punten A, B, C, DE , en F in het spel." Zoals u kunt zien, zijn de taken de afgelopen decennia duidelijk ingewikkelder geworden. En als gevolg daarvan zijn de gegevenstypen ingewikkelder geworden. Dit is nog een reden waarom OOP verscheen. Een wiskundige uitdrukking kan eenvoudig worden geëvalueerd met behulp van gewone primitieven. Hier zijn geen objecten nodig. Maar de taak met de speleindes zou zelfs moeilijk te beschrijven zijn zonder aangepaste klassen te gebruiken. Dat gezegd hebbende, het is vrij eenvoudig om het te beschrijven met behulp van klassen en objecten. Uiteraard hebben we verschillende klassen nodig: Game, Stalker, Ending, PlayerDecision, GameEvent, enzovoort. Met andere woorden, zelfs zonder het probleem op te lossen, kunnen we gemakkelijk een oplossing in ons hoofd 'schetsen'. De toenemende complexiteit van de taken dwong programmeurs om ze in delen op te delen. Maar dit was niet zo eenvoudig om te doen in procedurele programmering. En heel vaak was een programma als een boom met veel takken die alle mogelijke uitvoeringspaden vertegenwoordigden. Afhankelijk van bepaalde voorwaarden werd de ene of de andere tak van het programma uitgevoerd. Voor kleine programma's was dit handig, maar het was erg moeilijk om een ​​groot probleem in delen op te delen. Dit was nog een andere reden voor de opkomst van OOP. Dit paradigma gaf programmeurs de mogelijkheid om een ​​programma op te delen in een aantal "modules" (klassen), die elk hun eigen deel van het werk doen. Door met elkaar te interageren, volbrengen alle objecten het werk van ons programma. Daarnaast kunnen we onze code elders in het programma hergebruiken, wat ook weer een hoop tijd scheelt.
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION