Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo-ca-cd:laboratoare:design-avansat-de-clase [2025/10/13 21:08]
florian_luis.micu [Declararea și instanțierea claselor]
poo-ca-cd:laboratoare:design-avansat-de-clase [2025/10/13 22:40] (current)
florian_luis.micu [Laboratorul 2: Obiecte în Java]
Line 3: Line 3:
   * Autori: [[miculuis1@gmail.com | Florian-Luis Micu ]], [[sorinabuf@gmail.com | Sorina-Anamaria Buf ]], [[stefancocioran@gmail.com | Ștefan Cocioran ]]   * Autori: [[miculuis1@gmail.com | Florian-Luis Micu ]], [[sorinabuf@gmail.com | Sorina-Anamaria Buf ]], [[stefancocioran@gmail.com | Ștefan Cocioran ]]
   * Data publicării:​ 13.10.2025   * Data publicării:​ 13.10.2025
-  * Data ultimei modificări: ​13.10.2025+  * Data ultimei modificări: ​14.10.2025 
 +    * reordonarea secțiunilor,​ mutarea anumitor concepte în [Nice to know] și refrazări.  ​
  
 ===== Obiective ===== ===== Obiective =====
Line 25: Line 26:
   * Destructori.   * Destructori.
   * Scenariid de utilizare pentru static.   * Scenariid de utilizare pentru static.
 +  * Utilizarea corectă a array-urilor care conțin obiecte.
  
  
Line 81: Line 83:
  
 <note important>​ <note important>​
-Vom explica în acest laborator și în laboratoarele următoare mai multe proprietăți ale tipului ''​String''​.+  * Orice text inserat între **ghilimele** este considerat un **String literal**. 
 +  * Vom explica în acest laborator și în laboratoarele următoare mai multe proprietăți ale tipului ''​String''​.
 </​note>​ </​note>​
 =====🧱 Clase și obiecte===== =====🧱 Clase și obiecte=====
Line 145: Line 148:
 Java **nu permite pointeri direcți**, pentru a evita erorile de acces și scurgerile de memorie.  ​ Java **nu permite pointeri direcți**, pentru a evita erorile de acces și scurgerile de memorie.  ​
  
-În schimb, folosește **referințe**,​ care funcționează asemănător,​ dar sunt gestionate automat de JVM.+În schimb, ​Java folosește **referințe**,​ care funcționează asemănător,​ dar sunt gestionate automat de JVM prin **Garbage Collector** ceea ce înseamnă că programatorul **nu** se mai ocupă de gestionarea memoriei manual.
  
 <code java> <code java>
Line 151: Line 154:
 </​code>​ </​code>​
  
-Dacă referința nu a fost încă asociată unui obiect, valoarea sa este ''​null'',​ iar accesarea membrilor va produce o eroare de tip ''​NullPointerException''​. +Prin instanțierea unei clase se înțelege crearea unui obiect ​pe baza unei clase, adică alocarea unei zone de memorie pentru o instanță a clasei.
- +
-Prin instanțierea unei clase se înțelege crearea unui obiect ​care corespunde unui șablon definit. +
- +
-Procesul ​de inițializare implică: declarare, instanțiere și atribuire.+
  
-După ce am definit clasa ''​Apple''​putem crea obiecte ''​Apple''​folosind ​următoarea sintaxă+Procesul de inițializare implică: declarareinstanțiere și atribuireconform ​următoarei sintaxe:
  
 ''​Class''​ ''​numeVar''​ = ''​new''​ ''​Class()''​. ''​Class''​ ''​numeVar''​ = ''​new''​ ''​Class()''​.
Line 163: Line 162:
 Membrul stâng până la egal conține **referința** de tip ''​Class'',​ iar membrul drept conține **instanța** de tip ''​Class''​. Membrul stâng până la egal conține **referința** de tip ''​Class'',​ iar membrul drept conține **instanța** de tip ''​Class''​.
  
-Keyword-ul ''​new''​ este folosit pentru **crearea ​instanței** sau **crearea obiectului**, conform următorului exemplu:+Keyword-ul ''​new''​ este folosit pentru **alocarea memoriei** (instanțierea clasei), conform următorului exemplu:
  
 <code java> <code java>
Line 171: Line 170:
 Apple a2 = new Apple(); // declarare și instanțiere pe aceeași linie Apple a2 = new Apple(); // declarare și instanțiere pe aceeași linie
 </​code>​ </​code>​
 +
 +<note warning>
 +Dacă referința nu a fost încă asociată unui obiect, valoarea sa este ''​null'',​ iar accesarea membrilor va produce o eroare de tip ''​NullPointerException''​.
 +</​note>​
  
 <note important>​ <note important>​
Line 176: Line 179:
   * Rețineți că un **obiect** este de fapt o **clasă instanțiată**.   * Rețineți că un **obiect** este de fapt o **clasă instanțiată**.
   * Vom explica în secțiunile următoare de ce este nevoie să punem paranteze în membrul drept după numele clasei.   * Vom explica în secțiunile următoare de ce este nevoie să punem paranteze în membrul drept după numele clasei.
-</​note>​ 
- 
-<note warning> 
-Un obiect care nu este instanțiat are valoarea ''​null'',​ deoarece nu a fost alocată memorie pentru acesta. Deci considerăm că un obiect poate să fie **inițializat** sau ''​null'':​ 
- 
-<code java> 
-Apple a; 
-System.out.println(a);​ // se va afișa "​null"​ 
-</​code>​ 
 </​note>​ </​note>​
  
Line 198: Line 192:
 </​code> ​ </​code> ​
   ​   ​
-Aceasta este varianta **preferată** pentru instanțierea ​string-urilor. De remarcat că și varianta următoare este corectă, dar **ineficientă**,​ din motive ce vor fi explicate în următoarele laboratoare. ​+Aceasta este varianta **preferată** pentru instanțierea ​String-urilor. De remarcat că și varianta următoare este corectă, dar **ineficientă**,​ din motive ce vor fi explicate în următoarele laboratoare. ​
  
 <code java> ​ <code java> ​
Line 206: Line 200:
 ====Accesarea variabilelor și metodelor unui obiect==== ====Accesarea variabilelor și metodelor unui obiect====
  
-Odată creat obiectul, putem accesa ​variabilele ​și metodele ​sale folosind **dot notation** ''​.''​ după numele variabilei:+Odată creat obiectul, putem accesa ​membrii săi (variabile ​și metodelefolosind **dot notation** ​(''​.''​după numele variabilei:
  
 <code java PrintAppleDetails.java>​ <code java PrintAppleDetails.java>​
Line 240: Line 234:
  
 <note important>​ <note important>​
-  * În Java, câmpurile **neinițializate** primesc valoarea implicită 0 sau echivalentul acestei valori pentru tipul de date respectiv (ex. ''​bool''​ -> ''​false'',​ ''​float''​ -> ''​0.f''​). Din acest motiv, variabila membru ''​mass''​ are valoarea ''​0''​. +În Java, câmpurile **neinițializate** primesc valoarea implicită 0 sau echivalentul acestei valori pentru tipul de date respectiv (ex. ''​bool''​ -> ''​false'',​ ''​float''​ -> ''​0.f'',​ ''​Apple''​ -> ''​null''​). Din acest motiv, variabila membru ''​mass''​ are valoarea ''​0''​. ​Țineți cont că acestă inițializare default se întâmplă ​**doar pentru câmpuri** și **nu pentru variabilele locale** dintr-o metodă. 
-  ​* Metoda "​main"​ poate fi introdusă în **orice** clasă, puteți avea chiar mai multe metode "​main"​ în mai multe clase, dar doar o **singură** metodă "​main"​ poate fi pornită la un anumit moment de timp.+</​note>​ 
 + 
 +<note tip> 
 +Metoda "​main"​ poate fi introdusă în **orice** clasă, puteți avea chiar mai multe metode "​main"​ în mai multe clase, dar doar o **singură** metodă "​main"​ poate fi pornită la un anumit moment de timp.
 </​note>​ </​note>​
  
Line 260: Line 257:
 ===Variabile locale=== ===Variabile locale===
  
-O variabilă locală ​este+O variabilă locală: 
-  * creată la apelul metodei; +  * este creată la apelul metodei; 
-  * ștearsă automat când metoda se termină;+  * este ștearsă automat când metoda se termină;
   * trebuie inițializată înainte de a fi folosită.   * trebuie inițializată înainte de a fi folosită.
  
Line 274: Line 271:
  
 <note important>​ <note important>​
-Spre deosebire de variabilele instanței, variabilele locale **nu primesc valori implicite**. Dacă se încearcă folosirea unei variabile locale fără inițializare,​ se va afișa o **eroare de compilare**.+Spre deosebire de variabilele instanței ​(câmpuri), variabilele locale **nu primesc valori implicite**. Dacă se încearcă folosirea unei variabile locale fără inițializare,​ se va afișa o **eroare de compilare**.
 </​note>​ </​note>​
  
 ===Inițializarea variabilelor locale=== ===Inițializarea variabilelor locale===
  
-Java **nu permite** folosirea unei variabile locale fără inițializare sigură.+Java **nu permite** folosirea unei variabile locale fără ​**inițializare sigură**.
  
 Un exemplu de cod greșit este următorul: Un exemplu de cod greșit este următorul:
Line 299: Line 296:
 <code java> <code java>
 class Apple { class Apple {
-    int xy;+    int x = 2;  
 +    int = 3;
  
 +    // Presupunem că argumentele pasate sunt: x = 10, y = 11
     void moveTo(int x, int y) {     void moveTo(int x, int y) {
-        System.out.println("​Moving apple to " + x + ", " + y);+        System.out.println("​Moving apple to (" + x + ", " + y + "​)"​);
     }     }
 } }
 </​code>​ </​code>​
  
-În acest exemplu, ''​x''​ și ''​y''​ din metodă sunt **parametrii**,​ nu variabilele ale instanței. +<spoiler Output>​ 
-Pentru a accesa variabilele care aparțin ​instaței, trebuie să folosim keyword-ul ''​this'',​ prezentat mai jos.+<code bash> 
 +Moving apple to (10, 11) 
 +</​code>​ 
 +</​spoiler>​ 
 + 
 +În acest exemplu, ''​x''​ și ''​y''​ din metodă sunt **parametrii** ​metodei, nu variabilele ale instanței. 
 + 
 +Pentru a accesa variabilele care aparțin ​instanței, trebuie să folosim keyword-ul ''​this'',​ prezentat mai jos.
  
 ===Supraîncărcarea metodelor=== ===Supraîncărcarea metodelor===
Line 348: Line 354:
  
 Un alt exemplu cu care sunteți deja familiari este chiar metoda ''​print()''​ în care puteți introduce mai multe tipuri de argumente. Un alt exemplu cu care sunteți deja familiari este chiar metoda ''​print()''​ în care puteți introduce mai multe tipuri de argumente.
- 
-<code java> 
-class PrintStream { 
-    void print(char[] arg) { ... } 
-    void print(int arg) { ... } 
-    void print(double arg) { ... } 
-    // etc. 
-} 
-</​code>​ 
  
 <code java> <code java>
Line 364: Line 361:
 </​code>​ </​code>​
  
-==Cum alege compilatorul metoda corectă?== +<spoiler [Nice to know] Detalii despre algoritmul din spatele supraîncărcării>
 Compilatorul Java folosește următorul algoritm pentru supraîncărcare:​ Compilatorul Java folosește următorul algoritm pentru supraîncărcare:​
   - Caută o potrivire exactă a tipurilor de argumente.   - Caută o potrivire exactă a tipurilor de argumente.
Line 375: Line 371:
   * Vom detalia moștenirea în laboratorul următor.   * Vom detalia moștenirea în laboratorul următor.
 </​note>​ </​note>​
 +</​spoiler>​
  
 ====Crearea obiectelor==== ====Crearea obiectelor====
Line 400: Line 397:
    int day = 1;    int day = 1;
  
 +   // Constructor explicit adăugat de programator
    ​SpecialDate(int day) {    ​SpecialDate(int day) {
       this.day = day;       this.day = day;
Line 418: Line 416:
 SpecialDate date2 = new SpecialDate(30);​ SpecialDate date2 = new SpecialDate(30);​
 </​code>​ </​code>​
 +</​note>​
 +
 +<note tip>
 +Constructorii **nu au tip de return** pentru că returnează tipul clasei automat pentru instanțiere.
 </​note>​ </​note>​
  
 ===Supraincărcarea constructorilor=== ===Supraincărcarea constructorilor===
  
-Java permite existența mai multor constructori în aceeași clasă, cu semnături diferite. Alegerea constructorului potrivit se face la compilare, conform regulilor de selecție a metodelor supraincărcate.+Java permite existența ​**mai multor constructori** în aceeași clasă, cu **semnături diferite**. Alegerea constructorului potrivit se face la compilare, conform regulilor de selecție a metodelor supraincărcate.
  
 <code java> <code java>
Line 439: Line 441:
 } }
 </​code>​ </​code>​
 +
 +<note tip>
 +  * Puteți crea oricâți constructori doriți într-o clasă.
 +  * Din punct de vedere al coding style-ului vă recomandăm să ordonați constructorii după numărul de parametrii.
 +</​note>​
  
 ===Copy constructor=== ===Copy constructor===
  
-În Java, există conceptul de **copy constructor**,​ acesta reprezentând un constructor care ia ca parametru un obiect de același tip cu clasa în care se află constructorul respectiv. Cu ajutorul acestui constructor,​ putem să copiem obiecte, prin copierea membru cu membru în constructor.+În Java, există conceptul de **copy constructor**,​ acesta reprezentând un constructor care ia ca parametru un obiect de același tip cu clasa în care se află constructorul respectiv. Cu ajutorul acestui constructor,​ putem să **copiem obiecte**, prin copierea membru cu membru în constructor.
  
 <code java> <code java>
Line 456: Line 463:
     // copy constructor     // copy constructor
     public Student(Student student) {     public Student(Student student) {
-        /name este camp privat, noi il putem accesa direct (student.name)  +        /*  
-        // ​deoarece ne aflam in interiorul clasei+          "name" ​este câmp privat, noi îl putem accesa direct (student.name)  
 +          deoarece ne aflam in interiorul clasei 
 +        */
         this.name = student.name;​         this.name = student.name;​
         this.averageGrade = student.averageGrade;​         this.averageGrade = student.averageGrade;​
Line 500: Line 509:
 ===Garbage Collection=== ===Garbage Collection===
  
-Mecanismul de garbage collection are rolul de a **elibera memoria** ocupată de obiectele care nu mai sunt accesibile. Un obiect devine ​neaccesibil ​atunci când nu mai există **nicio referință activă** către el.+Mecanismul de garbage collection are rolul de a **elibera memoria** ocupată de obiectele care nu mai sunt accesibile. Un obiect devine ​inaccesibil ​atunci când nu mai există **nicio referință activă** către el.
  
 <code java> <code java>
Line 569: Line 578:
 ''​this''​ se folosește pentru: ''​this''​ se folosește pentru:
  
-1. **Dezambiguizare**,​ prin accesarea ​la variabile ​care aparțin instanței ce sunt ascunse de parametri:+1. **Dezambiguizare**,​ prin accesarea ​variabilelor ​care aparțin instanței ce sunt ascunse de parametri:
  
 <code java> <code java>
Line 629: Line 638:
 </​note>​ </​note>​
  
-3. **Apelul către un alt constructor din aceeași clasă:**+3. Apelul către un **alt constructor** din aceeași clasă:
  
-Keyword-ul ''​this''​ are un al treilea scenariu în care poate fi folosit, concret apelul ​către un alt constructor din aceeași clasă se face cu ''​this(...)''​ și trebuie să fie **prima instrucțiune** din constructorul curent.<​code java>+Apelul ​către un alt constructor din aceeași clasă se face cu ''​this(...)''​ și trebuie să fie **prima instrucțiune** din constructorul curent.<​code java>
 class Car { class Car {
     String model;     String model;
Line 645: Line 654:
             System.out.println("​Is this the batmobile?"​);​             System.out.println("​Is this the batmobile?"​);​
         }         }
-        this(model4); // eroare, apelul "​this"​ nu se află pe prima linie din constructor+        this("​Batmobile"​doors); // eroare, apelul "​this"​ nu se află pe prima linie din constructor 
 +    } 
 +     
 +    Car(String model) { 
 +        this(model, 4); // corect
     }     }
 } }
Line 651: Line 664:
  
 <note tip> <note tip>
-Java 25 permite ca apelul ''​this()''​ să nu se afle pe prima linie din constructor.+  * Java 25 permite ca apelul ''​this()''​ să nu se afle pe prima linie din constructor
 +  * Recomandăm refolosirea constructorilor pentru a evita **cod duplicat**.
 </​note>​ </​note>​
  
Line 745: Line 759:
 <code java> ​ <code java> ​
  class PropertiesExample {      ​  class PropertiesExample {      ​
-     ​String myString;+     private ​String myString;
            
-     ​String getMyString() {+     public ​String getMyString() {
          ​return myString;          ​return myString;
      }      }
            
-     void setMyString(String myString) {+     public ​void setMyString(String myString) {
          ​this.myString = myString;          ​this.myString = myString;
      }      }
Line 762: Line 776:
 PropertiesExample pe = new PropertiesExample(); ​ PropertiesExample pe = new PropertiesExample(); ​
  
-pe.setMyString("​This is my string!"​);​+pe.myString = "This is bad"; // nu funcționează pentru că este "​private"​ 
 + 
 +pe.setMyString("​This is my string!"​); ​// funcționează
  
 System.out.println(pe.getMyString()); ​ System.out.println(pe.getMyString()); ​
Line 918: Line 934:
 ==== Alocarea memoriei în Heap ==== ==== Alocarea memoriei în Heap ====
  
-Obiectele în Java sunt stocate în **heap**, o zonă de memorie dedicată alocărilor dinamice. ​  +Obiectele în Java sunt stocate în **Heap**, o zonă de memorie dedicată alocărilor dinamice. Pentru a crea un obiect, folosim operatorul ''​new''​.
-Pentru a crea un obiect, folosim operatorul ''​new''​, care: +
- +
-  * alocă spațiu în memoria heap; +
-  * apelează constructorul clasei; +
-  * returnează o **referință** către noul obiect, care este stocată pe stack.+
  
 <code java Student.java>​ <code java Student.java>​
Line 952: Line 963:
  
 În exemplul de mai sus: În exemplul de mai sus:
-  * referința ''​st''​ este pe **stack**; +  * referința ''​st''​ este pe **Stack**; 
-  * obiectul ''​Student''​ este alocat pe **heap**;+  * obiectul ''​Student''​ este alocat pe **Heap**;
   * adresa obiectului din heap este copiată în referința ''​st''​.   * adresa obiectului din heap este copiată în referința ''​st''​.
  
 {{:​poo-ca-cd:​laboratoare:​obiecte-in-java:​stack_and_heap_vars.png?​nolink&​750|}} {{:​poo-ca-cd:​laboratoare:​obiecte-in-java:​stack_and_heap_vars.png?​nolink&​750|}}
  
-Când metoda în care a fost creat obiectul se termină, referința ''​st''​ dispare, dar obiectul rămâne în heap până când **Garbage Collector-ul** decide că nu mai este utilizat+Când metoda în care a fost creat obiectul se termină, referința ''​st''​ dispare, dar obiectul rămâne în Heap până când **Garbage Collector-ul** decide că nu mai este utilizat ​(când numărul ​de referințe către acea zonă din Heap ajunge la 0).
- +
-<note tip> +
-Heap-ul este gestionat **automat** ​de JVM prin Garbage Collector, programatorul nu trebuie să elibereze manual memoria. +
-</​note>​+
  
  
Line 1031: Line 1038:
 </​spoiler>​ </​spoiler>​
  
-După cum se poate observa, ''​a1''​ și ''​a2''​ vor funcționa ca entități independente una de cealaltă, astfel că modificarea câmpului ''​mass''​ din ''​a1''​ nu va avea nici un efect implicit și automat în ''​a2''​. Există totuși situații când dorim să creăm câmpuri care să fie partajate și să nu fie memorate separat pentru fiecare instanță.+După cum se poate observa, ''​a1''​ și ''​a2''​ vor funcționa ca entități independente una de cealaltă, astfel că modificarea câmpului ''​mass''​ din ''​a1''​ nu va avea nici un efect implicit și automat în ''​a2''​. ​
  
 Membrii statici **nu aparțin unei instanțe** anume, ci **clasei** în sine. Aceștia sunt împărtășiți de-a lungul tuturor obiectelor create din acea clasă și pot să fie accesate **fără** să se creeze o instanță, având o locație specială în memorie (diferită de Heap și Stack). Membrii statici **nu aparțin unei instanțe** anume, ci **clasei** în sine. Aceștia sunt împărtășiți de-a lungul tuturor obiectelor create din acea clasă și pot să fie accesate **fără** să se creeze o instanță, având o locație specială în memorie (diferită de Heap și Stack).
Line 1039: Line 1046:
 Când declarați o variabilă sau o metodă înăuntrul unei clase: Când declarați o variabilă sau o metodă înăuntrul unei clase:
   * **Membrii instanței**:​ aparțin doar obiectului instanțiat. (ex. ''​a1.mass''​ și ''​a2.mass''​ pot avea valori diferite).   * **Membrii instanței**:​ aparțin doar obiectului instanțiat. (ex. ''​a1.mass''​ și ''​a2.mass''​ pot avea valori diferite).
-  * **Membrii statici**: aparțin clasei și sunt împărtășiți de către toate obiectele (ex. toate merele pot avea aceeași constantă gravitațională).+  * **Membrii statici**: aparțin clasei și sunt împărtășiți de către toate obiectele (ex. toate merele pot avea aceeași constantă gravitațională ​''​gravAcc''​).
  
 ^Tip^Apartenență^Accesat prin^Cum este valoarea reținută în memorie^ ^Tip^Apartenență^Accesat prin^Cum este valoarea reținută în memorie^
Line 1080: Line 1087:
 </​spoiler>​ </​spoiler>​
  
-<note tip> 
-Folosiți variabile statice pentru a avea **configurații împărtășite** sau **constante la nivel de clase**, nu pentru a stoca date per obiect. 
-</​note>​ 
  
 ====Accesarea membrilor statici==== ====Accesarea membrilor statici====
Line 1111: Line 1115:
    ​public static void main(String[] args) {    ​public static void main(String[] args) {
       float g = Apple.gravAcc;​       float g = Apple.gravAcc;​
 +      ​
 +      // Corect, dar nepreferat
 +      Apple a1 = new Apple();
 +      float g = a1.gravAcc;
    }    }
 } }
poo-ca-cd/laboratoare/design-avansat-de-clase.1760378893.txt.gz · Last modified: 2025/10/13 21:08 by florian_luis.micu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0