CodeGym /Blog Java /Aleatoriu /Principiile POO
John Squirrels
Nivel
San Francisco

Principiile POO

Publicat în grup
Bună! În lecția de astăzi, vom vorbi despre Principiile programării orientate pe obiecte. V-ați întrebat vreodată de ce Java este proiectat exact așa cum este? Adică, declari clase și creezi obiecte bazate pe clase, clasele au metode etc. Dar de ce limbajul este structurat astfel încât programele constau din clase și obiecte, și nu altceva? De ce a fost inventat și pus în prim plan conceptul de „obiect”? Toate limbile sunt concepute astfel? Dacă nu, ce avantaje îi oferă Java? După cum puteți vedea, există o mulțime de întrebări :) Să încercăm să răspundem la fiecare dintre ele în lecția de astăzi.

Ce este programarea orientată pe obiecte (OOP)?

Desigur, Java nu este alcătuit din obiecte și clase doar pentru distracție. Nu sunt un capriciu al creatorilor Java și nici măcar invenția lor. Există multe alte limbaje bazate pe obiecte. Primul astfel de limbaj a fost numit „Simula”. A fost inventat în anii 1960 în Norvegia. Mai mult, conceptele de „clasă” și „metodă” au apărut în Simula. După standardele dezvoltării software, „Simula” pare o limbă străveche, dar oricine poate vedea „asemănarea sa de familie” cu Java. Principiile programarii orientate pe obiecte - 1Probabil că puteți citi cu ușurință codul scris în această limbă și explicați în linii mari ce face :)

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;
Acest exemplu de cod de cod a fost preluat din „Simula - 50 de ani de OOP” de Weekly-geekly. După cum puteți vedea, Java nu este atât de diferit de bunicul său :) Acest lucru se datorează faptului că apariția Simula a marcat nașterea unui nou concept: programarea orientată pe obiecte. Wikipedia definește OOP astfel: „Object-Oriented Programming (OOP) este o paradigmă de programare bazată pe conceptul de „obiecte”, care poate conține date, sub formă de câmpuri (cunoscute adesea sub numele de atribute), și cod, sub forma a procedurilor (cunoscute adesea ca metode)." După părerea mea, aceasta este o definiție foarte bună. Nu a fost cu mult timp în urmă când ați început să învățați Java, dar această definiție probabil nu conține niciun cuvânt pe care să nu-l cunoașteți :) Astăzi OOP este cea mai comună metodologie de programare. Pe lângă Java, Principiile POO sunt folosite în multe limbi populare despre care probabil ați auzit. De exemplu, C++ (utilizat activ în dezvoltarea jocurilor), Objective-C și Swift (folosit pentru a scrie programe pentru dispozitive Apple), Python (cel mai popular în învățarea automată), PHP (unul dintre cele mai populare limbaje de dezvoltare web), JavaScript ( este mai ușor să spui la ce nu este folosit) și multe altele. Deci, care sunt principiile POO? Vă vom spune în detaliu. care sunt oricum principiile OOP? Vă vom spune în detaliu. care sunt oricum principiile OOP? Vă vom spune în detaliu.

Principiile POO

Acestea sunt fundația fundației. Cele 4 caracteristici principale care formează împreună paradigma de programare orientată pe obiecte. Înțelegerea lor este esențială pentru a deveni un programator de succes.

Principiul 1. Moștenirea

Vești bune: cunoașteți deja câteva dintre principiile OOP! :) Am întâlnit deja de câteva ori moștenirea la lecții și am reușit să o folosim. Moștenirea este un mecanism care vă permite să descrieți o nouă clasă bazată pe o clasă existentă (părinte). Procedând astfel, noua clasă împrumută proprietățile și funcționalitatea clasei părinte. Pentru ce este moștenirea și ce avantaje oferă? Mai presus de toate, reutilizarea codului. Câmpurile și metodele declarate în clasele părinte pot fi folosite în clasele descendente. Dacă toate tipurile de mașini au 10 câmpuri comune și 5 metode identice, trebuie doar să le mutați în Autoclasa de părinți. Le poți folosi în clasele descendențe fără probleme. Avantaje solide: atât cantitative (mai puțin cod), cât și, ca urmare, calitative (clasele devin mult mai simple). În plus, moștenirea este foarte flexibilă - puteți adăuga funcționalități separate de scriere care le lipsesc descendenților (unele câmpuri sau comportamente care sunt specifice unei anumite clase). În general, ca și în viața reală, toți suntem oarecum asemănători cu părinții noștri, dar și cumva diferiți de ei :)

Principiul 2. Abstracția

Acesta este un principiu foarte simplu. Abstracția înseamnă a identifica principalele, cele mai semnificative caracteristici ale ceva, în timp ce în același timp aruncăm orice lucru minor și nesemnificativ. Nu este nevoie să reinventezi roata. Să ne amintim un exemplu dintr-o lecție veche despre cursuri. Să presupunem că creăm un sistem de înregistrare pentru angajații companiei. Pentru a crea obiecte „angajați”, am scris o clasă de angajat . Ce caracteristici sunt importante pentru a le descrie în sistemul de înregistrare a companiei? Numele, data nașterii, SSN și ID-ul angajatului. Dar este puțin probabil să avem nevoie de înălțimea, culoarea ochilor sau culoarea părului angajatului pentru acest tip de înregistrare. Compania nu are nevoie de astfel de informații despre un angajat. Deci, în clasa Employee , declarăm următoarele variabile:, int age , int socialSecurityNumber și int employeeId . Și extragem informații inutile, cum ar fi culoarea ochilor. Cu toate acestea, dacă facem un sistem de înregistrare pentru o agenție de modele, situația se schimbă dramatic. Înălțimea unui model, culoarea ochilor și culoarea părului sunt caracteristici importante, dar SSN-ul ei este absolut irelevant pentru noi. Deci, în clasa Model , creăm următoarele variabile: String height , String hair , String eyes .

Principiul 3. Încapsulare

Ne-am lovit deja de asta. În Java, încapsularea înseamnă restricționarea capacității de a citi și modifica datele. După cum puteți vedea, termenul se bazează pe cuvântul „capsulă”. Vom folosi o „capsulă” pentru a ascunde unele date importante pe care nu dorim să le modifice altele. Iată un exemplu simplu din viața reală. Ai un prenume și un nume de familie. Toți prietenii tăi le cunosc. Dar ei nu au capacitatea de a vă schimba numele sau prenumele. Am putea spune că procesul pentru a face acest lucru este „încapsulat” de sistemul judiciar: îți poți schimba numele de familie doar prin intermediul grefierului și doar tu o poți face. Alți „utilizatori” au acces „numai în citire” la numele și prenumele dvs. :) Un alt exemplu ilustrativ este numerarul păstrat acasă. Să-l lași la vedere în mijlocul camerei tale nu este o idee bună. Orice „utilizator” (persoana care vine la tine acasa) va putea schimba suma banilor tai, adica iti poate lua banii. Ar fi mai bine să-l încapsulați într-un seif. Apoi accesul va fi disponibil numai pentru dvs. și numai prin utilizarea unui cod special. Exemple evidente de încapsulare cu care ați lucrat deja sunt modificatorii de acces (privați, publici etc.), precum și setterii și geterii. Dacă nu încapsulațiCâmpul de vârstă al clasei de pisici , atunci oricine poate scrie:

Cat.age = -1000;
Mecanismul de încapsulare ne permite să protejăm câmpul de vârstă cu o metodă setter, în care ne putem asigura că vârsta nu poate fi setată la un număr negativ.

Principiul 4. Polimorfismul

Polimorfismul este capacitatea de a lucra cu mai multe tipuri ca și cum ar fi același tip. Mai mult, comportamentul obiectelor va fi diferit în funcție de tipul lor. Sună complicat? Să înțelegem asta chiar acum. Luați cel mai simplu exemplu: animalele. Creați o clasă Animal cu o singură metodă speak() și două subclase - Cat și 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!");
   }
}
Acum vom încerca să declarăm o variabilă de referință Animal și să îi atribuim un obiect Dog .

public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.speak();
   }
}
Ce metodă crezi că se va numi? Animal.speak() sau Dog.speak() ? Metoda din clasa Dog se va numi: Woof-woof! Am creat o referință Animal , dar obiectul se comportă ca un Câine . Dacă este necesar, s-ar putea comporta ca o pisică, un cal sau un alt animal. Important este să atribuiți o anumită subclasă variabilei generale de referință Animal . Acest lucru are sens, deoarece toți câinii sunt animale. La asta ne-am gândit când am spus „comportamentul obiectelor va fi diferit în funcție de tipul lor”. Dacă am creat un obiect Cat ...

public static void main(String[] args) {

   Animal cat = new Cat();
   cat.speak();
}
metoda speak () ar afișa „Miau!” Dar ce înțelegem prin „abilitatea de a lucra cu mai multe tipuri ca și cum ar fi același tip”? Acest lucru este, de asemenea, destul de simplu. Să ne imaginăm că creăm o frizerie pentru animale. Frizeria noastră ar trebui să poată oferi o tăiere oricărui animal, așa că creăm o metodă trim() cu un parametru Animal (animalul care se tunsește).

public class AnimalBarbershop {

   public void trim(Animal animal) {

       System.out.println("The haircut is done!"); 
   }
}
Și acum putem trece obiectele Cat și Dog la metoda trim() !

public static void main(String[] args) {

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

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.trim(cat);
   barbershop.trim(dog);
}
Și iată exemplul clar: clasa AnimalBarbershop funcționează cu tipurile Cat și Dog ca și când ar fi același tip. În același timp, pisica și câinele au comportamente diferite: fiecare vorbește diferit.

De ce avem nevoie de OOP?

De ce a apărut vreodată OOP ca un nou concept de programare? Programatorii aveau instrumente funcționale, cum ar fi limbaje procedurale. Ce i-a determinat să inventeze ceva fundamental nou? Mai presus de toate, complexitatea sarcinilor cu care s-au confruntat. Dacă acum 60 de ani sarcina programatorului era ceva de genul „evaluarea unei expresii matematice”, acum ar putea fi ceva de genul „implementarea a 7 terminații diferite pentru jocul STALKER, în funcție de combinațiile deciziilor jucătorului luate la punctele A, B, C, DE , și F în joc." După cum puteți vedea, sarcinile au devenit, evident, mai complicate în ultimele decenii. Și, ca urmare, tipurile de date au devenit mai complicate. Acesta este un alt motiv pentru care a apărut OOP. O expresie matematică poate fi evaluată cu ușurință folosind primitive obișnuite. Nu sunt necesare obiecte aici. Dar sarcina cu finalul jocului ar fi greu de descris chiar și fără a folosi clase personalizate. Acestea fiind spuse, este destul de ușor să-l descrii folosind clase și obiecte. Evident, vom avea nevoie de mai multe clase: Joc, Stalker, Ending, PlayerDecision, GameEvent și așa mai departe. Cu alte cuvinte, chiar și fără a începe să rezolvăm problema, ne putem „schiță” cu ușurință o soluție în capul nostru. Complexitatea tot mai mare a sarcinilor i-a forțat pe programatori să le împartă în părți. Dar acest lucru nu a fost atât de ușor de făcut în programarea procedurală. Și destul de des un program era ca un copac cu o mulțime de ramuri reprezentând toate căile de execuție posibile. În funcție de anumite condiții, a fost executată o ramură sau alta a programului. Pentru programele mici, acest lucru a fost convenabil, dar a fost foarte dificil să împărțiți o problemă mare în părți. Acesta a fost încă un motiv pentru apariția OOP. Această paradigmă le-a oferit programatorilor capacitatea de a împărți un program într-o grămadă de „module” (clase), fiecare dintre ele își face propria parte a muncii. Prin interacțiunea între ele, toate obiectele realizează munca programului nostru. În plus, ne putem reutiliza codul în altă parte a programului, ceea ce economisește și mult timp.
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION