Wednesday, June 19, 2019 00:44

Instanțierea

Am explicat deja de câteva ori că atunci când avem de-a face cu obiecte, de cele mai multe ori nu lucrăm cu clasa originală în sine – schița, ci de fapt creăm copii ale acesteia, numite instanțe. Instanțierea este procesul de creare a unei instanțe (copie) a unei clase (schița). În această lumină, putem spune că un obiect este instanța însăși.

După cum am explicat deja în câteva ocazii, ne putem imagina acest proces de clase și instanțierea lor, făcând o similitudine cu lumea reală. În lecțiile anterioare, am folosit clasa Cuptor pentru a demonstra scopul de a crea un obiect de tip Cuptor. În viața reală, acesta ar fi schița, prototipul cuptorului. În practică, nu vom face o nouă schiță sau prototip de fiecare dată când vom vinde un cuptor. În schimb, vom folosi schița pentru a crea mai multe copii ale acesteia, care pot fi vândute. Copiile pot fi personalizate, de exemplu, un set de cuptoare poate avea culoarea albă, în timp ce un altul poate fi gri. Modelul original și unic nu specifică o culoare pentru cuptor, ci doar specifică faptul că obiectul cuptor poate avea o culoare.

În mod similar, atunci când creăm o clasă, de fapt creăm o schiță. Când vom dori să folosim această clasă, foarte rar vom folosi clasa însăși. În schimb, vom crea copii ale acesteia, numite instanțe. Aceste instanțe pot fi personalizate și sunt independente unele de altele.

În manualele oficiale de programare, veți întâlni doi termeni: starea unui obiect (state) și comportamentul acestuia (behavior). În timp ce starea obiectului este specifică fiecărui obiect (de exemplu, culoarea sau modelul obiectului nostru Cuptor, care poate fi individualizat pentru fiecare element), comportamentul este comun pentru toate instanțele clasei respective (toate obiectele Cuptor au o metodă Porneste() sau Opreste()).

Dar, destul cu vorbitul. Să vedem de fapt modul în care instanțiem o clasă, deși deja am făcut acest lucru de câteva ori:

Deci, modul în care instanțiem o clasă este folosirea numelui clasei care urmează să fie instanțiată, urmată de numele pe care dorim să-l dăm noului nostru obiect (copiei). Dacă priviți cu atenție, este similar cu acest lucru:

Începe să arate familiar? Am învățat deja că modul în care declarăm o variabilă este prin specificarea tipului său, urmat de nume. Deci, vedem că această instanțiere nu este altceva decât crearea unei variabile, de tip particularizat. În loc să creați un tip primitiv (tipurile definite în mod implicit în C#), creați un tip nou. În concluzie, declarăm o nouă variabilă de tip Cuptor.

Totul bine până acum. Dar am aflat că pentru a folosi o variabilă pe care am declarat-o, trebuie mai întâi să o inițializăm cu o valoare. Nu este permis să facem acest lucru:

la fel cum nu putem face acest lucru:

deoarece compilatorul se va plânge despre utilizarea unei variabile neinitalizate (Use of of unassigned variable).

Știm că putem inițializa o variabilă astfel:

Dar, în cazul variabilei noastre Cuptor, nu putem specifica o valoare implicită, deoarece nu există o valoare implicită specificată pentru tipul nostru personalizat. În schimb, trebuie să apelăm constructorul clasei, despre care am vorbit în lecția anterioară.

Singurul lucru nou din codul de mai sus este utilizarea operatorului new. Ceea ce nu știți este faptul că fiecare tip are un constructor, chiar și cei primitivi. Acest exemplu funcționează perfect:

caz în care variabilaMea este inițializată la valoarea implicită a tipului int. Acest lucru este echivalent cu

Speculațiile de mai sus nu valorează prea mult, ele sunt folosite doar pentru a dovedi și a diseca un concept în detaliu. Pe scurt, pentru a crea și utiliza o variabilă, trebuie să o declarăm și să o inițializăm. Acest lucru este valabil și pentru obiecte, cu o serie de diferențe:

  • Declararea și inițializarea obiectelor este numită și instanțiere.
  • Obiectele pot fi inițializate numai prin apelarea constructorului lor.
  • Apelarea constructorului unui obiect necesită întotdeauna folosirea operatorului new înainte de apel.
  • Toate tipurile primitive (int, float, bool, etc) cu excepția string sunt tipuri de valoare. Obiectele sunt întotdeauna tipuri de referință.

Deoarece am creat prima noastră clasă folosind un fișier separat, trebuie să precizez că pentru a declara și a folosi obiectele derivate din această clasă, avem nevoie de un loc diferit pentru a face acest lucru, nu putem face acest lucru în interiorul aceleași clase. În schimb, le declarăm și le inițializăm în metoda Main() a programului nostru. Acesta este modul în care ar trebui să arate fișierul nostru clasă:

clasa cuptor

Și acesta este locul în care o instanțiem:

Instanțierea claselor

Desigur, dacă am declarat un constructor cu parametri, îi specificăm în apelul de instanțiere:

După ce l-am instanțiat, putem începe să accesăm proprietățile și metodele obiectului nostru. Le veți observa în Intellisense, de îndată ce veți începe să tastați:

accesarea membrilor clasei

Și putem să atribuim valori sau să efectuăm acțiuni asupra lui:

Notă finală, atunci când creați un obiect cu operatorul new, se întâmplă două lucruri: memoria este rezervată pentru acest obiect, și membrii săi de date sunt inițializați. Aceasta înseamnă că:

nu ne va da o eroare de compilator, chiar dacă nu am inițializat în mod specific proprietatea Greutate cu o oarecare valoare. În schimb, consola va afișa valoarea implicită pentru tipul proprietății Greutate, în acest caz 0, deoarece 0 este valoarea implicită pentru tipul int.

Comments

comments

Tags: , , , , , ,

Leave a Reply