Saturday, December 04, 2021 20:04

Cuprins >> Obiecte > Constructori

Constructori

În programarea orientată pe obiecte, atunci când creați obiecte din anumite clase, este uneori necesar să apelați câteva metode speciale ale acelor clase, cunoscute sub numele de constructori.

Constructorul unei clase este o pseudo-metodă care nu returnează un tip, are același nume cu cel al clasei și se apelează utilizând cuvântul cheie new. Sarcina constructorului este aceea de a inițializa memoria alocată pentru obiect, unde vor fi stocate câmpurile sale (cele care nu sunt statice – vom afla despre ceea ce înseamnă static în viitor).

Să luăm din nou clasa Cuptor, de acum două lecții:

În lecția anterioară am aflat ce sunt câmpurile și proprietățile, și deja cunoaștem conceptul de metode. Deci, în codul de mai sus, există o singură bucată rămasă neanalizată încă. Anume, aceasta:

Semi-metoda de mai sus se numește constructorul clasei noastre. De ce o numesc semi-metodă? Ei bine, puteți vedea în mod clar că nu returnează un tip, ceea ce o exclude din categoria funcții, dar de asemenea nu folosește cuvântul cheie void,  așa cum orice metodă ar trebui.

Un alt lucru pe care l-ați observat este că identificatorul (numele) constructorului este identic cu identificatorul clasei. Să vedem ce s-ar fi întâmplat dacă am fi numit constructorul în mod diferit:

Codul de mai sus ne va da o eroare: Metoda trebuie să returneze un tip (Method must have a return type). Deci, compilatorul nu o mai recunoaște ca fiind un constructor, ci mai degrabă încearcă să o trateze ca o funcție obișnuită. Din acest lucru, rezultă următoarea concluzie: în C# este obligatoriu ca numele fiecărui constructor să fie identic cu numele clasei în care este declarat. De asemenea, nu este permisă declararea unei metode al cărei nume este identic cu numele clasei (și implicit, numele constructorilor). Dacă totuși, o metodă este declarată cu același nume cu al clasei, aceasta va cauza o eroare de compilare ‘Cuptor’: numele de membri nu pot fi identice cu tipul ce le înglobează (‘Cuptor’: member names cannot be the same as their enclosing type).

Modul în care declarăm un constructor este oarecum similar cu modul în care declarăm metodele:

Despre modificatori vom învăța în viitor, deși am întâlnit deja câțiva dintre ei (private, public, static). În afară de aceasta, lista de parametri este similară cu modul în care declarăm metodele cu parametri. În următoarea lecție, vom învăța cum să creăm copii ale schiței obiectelor noastre. Dar, așa cum am învățat în lecția Proprietăți, copiile noastre nu ne-ar fi de mare folos dacă nu le-am putea individualiza:

Exemplul de mai sus funcționează perfect, dar are multe linii, mai ales dacă trebuie să specificăm o mulțime de proprietăți. În schimb, am putea să facem acest lucru direct atunci când creăm copia obiectului, utilizând un constructor cu parametri. Să spunem că avem acest cod:

După aceea, putem crea o copie a obiectului după cum urmează:

Un mod mult mai scurt și mai elegant de a defini o copie nouă! Un lucru de observat aici – am definit variabilele parametrilor cu același nume cu al câmpurile noastre. Asta lucru este total acceptabil. De asemenea, observați că domeniul de definiție al parametrilor constructorilor este identic cu domeniul parametrilor metodelor obișnuite: este disponibil numai pentru corpul constructorului. Deși există o capcană în privința acestui fapt. Am explicat anterior că folosirea cuvântului cheie this este opțională, și indică faptul că ne referim la chestiuni legate de copia curentă a obiectului pe care îl manipulăm la momentul respectiv. Deci, am fi putut scrie acest lucru:

Dar în acest caz, am face o greșeală fatală, pentru că fără cuvântul cheie this, nu facem referire de fapt la câmpurile noastre, ci la variabilele parametru ale constructorului nostru. Deci, în loc să atribuim valoarea parametrilor câmpurilor noastre, de fapt atribuim variabilelor parametrilor propriile lor valori. Acesta este unul dintre motivele pentru care am spus că deși opțional, este indicat să folosim întotdeauna this atunci când ne referim la o instanță.

Alte asemănări cu metodele: constructorii noștri pot avea parametri opționali și, de asemenea, putem avea constructori supraîncărcați:

Ce se întâmplă când nu furnizăm deloc un constructor? Ca și în multe alte cazuri, compilatorul va crea un constructor implicit pentru noi, care este gol, nu are parametri și nici nu conține un cod în corpul său, și care nu face nimic altceva decât să inițializeze câmpurile noastre cu valoarea implicită a tipului lor. Acest tip de constructor se numește constructor implicit prestabilit. Aceasta înseamnă că nu este obligatoriu să creați o clasă cu un constructor, dacă nu aveți nevoie de un cod de inițializare la instanțierea clasei voastre. În cele din urmă, trebuie să știți că un constructor implicit prestabilit nu are aceeași semnătură ca un constructor fără parametri! Un constructor implicit prestabilit va avea întotdeauna nivelul de acces protected sau public (vom afla despre acest lucru în viitor) – în funcție de nivelul de acces al clasei în sine, în timp ce un constructor fără parametri declarat în mod specific de noi va avea orice nivel de acces îi oferim acestuia.

În următoarea lecție, vom vedea și modul de a apela constructorii, deoarece nu pot fi apelați în modul obișnuit de apelare al metodelor.

În concluzie, constructorul este punctul de intrare al clasei noastre, așa cum metoda Main() este punctul de intrare al programului nostru: este primul lucru care este executat atunci când se realizează instanțializarea unei clase. Dacă vrem să executăm automat un cod atunci când creăm o copie a unei clase, o putem facem folosind constructori.

Tags: , ,

Leave a Reply



Follow the white rabbit