Sunteți pe pagina 1din 4

Follow the white rabbit

They are watching you, Neo!


Sunday, December 15, 2019 09:23

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:

1 class Cuptor
2 {
3     private string model; // Campul "model"
4     private string culoare;
5     private int greutate;
6     private int inaltime;
7     private int latime;
8     private int lungime;
9  
10     public string Model // Proprietatea "Model"
11     {
12         get // Getter-ul proprietatii "Model"
13         {
14             return this.model;
15         }
16         set // Setter-ul proprietatii "Model"
17         {
18             this.model = value;
19         }
20     }
21  
22     public string Culoare
23     {
24         get { return this.culoare; }
25         set { this.culoare = value; }
26     }
27  
28     public int Greutate
29     {
30         get { return this.greutate; }
31         set { this.greutate = value; }
32     }
33  
34     public int Inaltime
35     {
36         get { return this.inaltime; }
37         set { this.inaltime = value; }
38     }
39  
40     public int Latime
41     {
42         get { return this.latime; }
43         set { this.latime = value; }
44     }
45  
46     public int Lungime
47     {
48         get { return this.lungime; }
49         set { this.lungime = value; }
50     }
51  
52     public Cuptor() // Constructor prestabilit
53     {
54         this.model = "EKK6450AOX";
55         this.culoare = "Gri";
56         this.greutate = 40;
57         this.inaltime = 85;
58         this.latime = 60;
59         this.lungime = 60;
60     }
61  
62     public void Porneste() // Metoda Porneste
63     {
64         Console.WriteLine("Cuptor pornit!");
65     }
66  
67     public void Opreste()
68     {
69         Console.WriteLine("Cuptor oprit!");
70     }
71 }

Î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:

1 public Cuptor() // constructor prestabilit


2 {
3     this.model = "EKK6450AOX";
4     this.culoare = "Gri";
5     this.greutate = 40;
6     this.inaltime = 85;
7     this.latime = 60;
8     this.lungime = 60;
9 }

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:

1 class Cuptor
2 {
3    public UnNumeDeConstructor()
4    {
5  
6    }
7 }

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:

1 <modificatori> <nume_clasa>(<lista_parameti>)

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:
1 Cuptor copieCuptor = new Cuptor();
2 copieCuptor.Model = "EKK6450AOX";
3 copieCuptor.Culoare = "alb";

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:

1 class Cuptor
2 {
3     private string model; // Campul "model"
4     private string culoare;
5     private int greutate;
6     private int inaltime;
7     private int latime;
8     private int lungime;
9  
10     public string Model
11     {
12         get { return this.model; }
13         set { this.model = value; }
14     }
15  
16     public string Culoare
17     {
18         get { return this.culoare; }
19         set { this.culoare = value; }
20     }
21  
22     public int Greutate
23     {
24         get { return this.greutate; }
25         set { this.greutate = value; }
26     }
27  
28     public int Inaltime
29     {
30         get { return this.inaltime; }
31         set { this.inaltime = value; }
32     }
33  
34     public int Latime
35     {
36         get { return this.latime; }
37         set { this.latime = value; }
38     }
39  
40     public int Lungime
41     {
42         get { return this.lungime; }
43         set { this.lungime = value; }
44     }
45  
46     public Cuptor()
47     {
48         this.model = "EKK6450AOX";
49         this.culoare = "Gri";
50         this.greutate = 40;
51         this.inaltime = 85;
52         this.latime = 60;
53         this.lungime = 60;
54     }
55 }

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

1 Cuptor copieCuptor = new Cuptor("EKK6450AOX", "alb", 40, 85, 60, 60);


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:

1 class Cuptor
2 {
3     //campuri aici
4  
5     public Cuptor(string model, string culoare, int greutate, int inaltime, int latime, int lungime)
6     {
7         model = model;
8         culoare = culoare;
9         greutate = greutate;
10         inaltime = inaltime;
11         latime = latime;
12         lungime = lungime;
13     }
14 }

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:

1 class Cuptor
2 {
3     public Cuptor() //fara parametri
4     {        
5     }
6  
7     public Cuptor(string model) //un parametru
8     {        
9     }
10  
11     public Cuptor(string model, string culoare) //doi parametri
12     {        
13     }
14 }

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.

Comments
0 comments

S-ar putea să vă placă și