Curs 1: Lucrul cu obiecte JAVA PDF
Document Details
Tags
Summary
This document provides an overview of Java object creation, initialization, and the use of constructors. Topics include object creation, initialization techniques, and the role of constructors in object initialization. The document also touches on initializing data structures like arrays in Java programming.
Full Transcript
Curs 1: Lucrul cu obiecte JAVA Crearea obiectelor Java. Inițializări specifice Metoda constructor, Cuvântul cheie this, Inițializări în interiorul unei clase Inițializarea masivelor de date 1. Crearea și distrugerea obiectelor Inițializarea corectă a variabilelo...
Curs 1: Lucrul cu obiecte JAVA Crearea obiectelor Java. Inițializări specifice Metoda constructor, Cuvântul cheie this, Inițializări în interiorul unei clase Inițializarea masivelor de date 1. Crearea și distrugerea obiectelor Inițializarea corectă a variabilelor și obiectelor, precum și ștergerea acestora atunci când misiunea lor a fost îndeplinită reprezintă două elemente cheie ale unei implementări sigure. Programarea orientată obiect acordă o atenție deosebită acestor două probleme. În acest sens C++ introduce conceptul de constructor, implementat sub forma unei metode apelate automat la crearea unui obiect. JAVA a preluat metoda constructor. Platforma conține și un garbage collector, ce eliberează automat resursele de memorie de obiectele ieșite din uz. Curs 1 2 2. Metoda constructor Determină inițializarea oricărui obiect ce aparține clasei în care a fost definită Poartă numele clasei - se evită confuzia de nume cu oricare alt membru al clasei - compilatorul o va recunoaște în vederea apelului automat la crearea oricărui obiect În constructor este primul mesaj trimis unui obiect. Ca orice metodă, constructorul: - poate avea sau nu argumente de apel; - argumentele permit identificarea diferitelor instanțe ale unei clase unice Nu returnează nimic și, spre deosebire de o metodă de tip void, programatorului nu i se permite nici un fel de opțiune pentru o valoare de ieșire. Curs 1 3 3. Supraîncărcarea constructorilor (overloading) JAVA a trebuit să soluționeze prin elemente de limbaj problema inițializării obiectelor unei clase în maniere diferite, dar folosind un singur nume de apel pentru constructor (numele clasei) Astfel, s-a dezvoltat conceptul de supraîncărcare a numelui constructorului (overloading). Implementarea acestuia duce la apelul, cu același mnemonic a unor metode diferite Supraîncărcarea permite, în JAVA, crearea în moduri diferite a obiectelor ce aparţin unei clase unice Curs 1 4 3. Supraîncărcarea constructorilor - exemplu Output: Curs 1 5 3. Supraîncărcarea constructorilor – explicații cod Metoda de tip constructor implicit nu are argumente de apel. Se poate defini un constructor explicit fără argumente. După cum s-a observat în cazul definițiilor metodei info( ), procesul de supraîncărcare poate fi aplicat și metodelor obișnuite; el permite realizarea unor acțiuni diferite sub un nume unic de apel. JAVA deosebește metodele supraîncărcate prin lista de argumente de apel. Direcționarea către o implementare anume se realizează prin respectarea - numărului - ordonării ca tip a argumentelor de apel. Curs 1 6 4. Cuvântul cheie “this” – pentru referință Prin mesaj valid se înțelege un apel de metodă pentru o instanță specificată a unei clase. Evident, același mesaj poate fi transmis mai multor obiecte de același tip. Pentru fiecare dintre acestea, compilatorul va realiza o conexiune internă obiect – metodă. În acest moment se ridică o nouă problemă: cum se poate referi un obiect din interiorul unei metode ce a fost apelată chiar pentru acel obiect? Soluția rezidă în folosirea cuvântului cheie this; acesta accesează referința obiectului pentru care a fost apelată metoda. În acest context this va fi tratat ca orice referință la un obiect. Folosirea lui this este permisă doar pentru a accede la obiectul pentru care s-a apelat metoda; deci this este, undeva, în codul de definiție al metodei. Curs 1 7 4. Cuvântul cheie “this” - pentru referință; exemplu O utilizare frecventă a lui this este în cazurile în care valoarea de retur a metodei este referința obiectului pentru care a fost apelată metoda: Output: Curs 1 8 4. Cuvântul cheie “this” – pentru apelare constructor Un caz practic de apel al lui this este atunci când se definesc clase cu mai multe metode constructor Se poate apela un constructor din interiorul altuia, evitându-se astfel duplicarea codului. Folosirea lui this în interiorul unui constructor se poate realiza: pentru acces la referința obiectului curent (this fără argumente); pentru a apela un anumit constructor (this cu argumente; se apelează acea metodă constructor pentru care lista de argumente din this este validă): Curs 1 9 Cuvântul cheie “this” “this” pentru apel de constructor Output: Curs 1 10 4. Cuvântul cheie “this” – explicații cod Codul sursă scoate în evidentă: atunci când se folosește this într-o metodă de tip constructor, apelul său este primul lucru realizat în metodă (în caz contrar apare o eroare de compilare); nume apare și ca dată de tip șir din clasă și ca argument de tip șir al unui constructor; this este folosit, în acest caz, pentru a rezolva ambiguitatea (this.nume se referă la un membru al clasei). Observaţie: apelul unei metode constructor este permis decât dintr-un alt constructor și numai o singura data. Curs 1 11 5. Inițializarea variabilelor unei clase În JAVA variabilele pot fi membri ai unei clase (câmpuri) sau ai unei metode. Dacă o variabilă este definită locală într-o metodă, ea va trebui iniţializată, în mod obligatoriu, de utilizator. În caz contrar va apărea un mesaj de eroare în faza de compilare. Modul de iniţializare descris până acum este simplu şi permite aceeaşi iniţializare pentru toate obiectele nou create ce aparţin unei clase. Dacă, însă, se doreşte sporirea flexibilităţii prin iniţializarea diferită pentru obiecte de acelaşi tip, se va folosi metoda constructor. Aceasta nu exclude iniţializarea implicită ce, oricum, se realizează înaintea activităţii constructorului. Curs 1 12 5. Inițializarea variabilelor unei clase – ordinea initializării Ordinea de inițializare, în interiorul unei clase, depinde de ordinea în care sunt definite variabilele. În acest mod se garantează inițializarea înaintea apelului oricărei metode (inclusiv a metodei constructor): Dacă, însă, aceeaşi variabilă este membru al unei clase, ea poate fi iniţializată și/sau folosită de orice metodă din respectiva clasă. Din această cauză, deși ea poate fi inițializată de programator, nu este indicat să se realizeze acest proces înainte de utilizarea efectivă a acesteia. Pe de altă parte, este riscant să fie lăsată o valoare oarecare în locaţia rezervată variabilei; din acest motiv JAVA folosește inițializarea implicită pentru toate tipurile primitive pe următoarele valori Curs 1 13 5. Inițializarea variabilelor unei clase Dacă se dorește o inițializare pe valori specificate de utilizator, acest lucru se poate realiza în momentul definirii variabilei Valori la inițializarea implicită Curs 1 14 5. Inițializarea variabilelor unei clase Obiectele se inițializează cu ajutorul cuvântului cheie new: NonPrimitiv a = new NonPrimitiv(); Dacă obiectul a nu a fost inițializat și se încearcă ulterior folosirea lui va apărea o eroare în faza de rulare (o excepție). NonPrimitiv b; b.toString(); // excepție Observație: în cazul apelurilor de metode, argumentele acestora, dacă există, trebuie să fie numai membri inițializați ai clasei căreia îi aparțin. Accidental sau dorit, se poate trimite ca parametru un obiect null. Curs 1 15 5. Inițializarea variabilelor unei clase – ordinea de inițializare Output: Curs 1 16 5. Inițializarea variabilelor unei clase – explicații cod În definiția clasei Cartela, în mod intenționat inițializarea obiectelor Indicator este dispersată. Se demonstrează, astfel, că inițializarea este efectuată înainte de intrarea constructorului sau a oricărei metode în acțiune. Referința ind3 este iniţializată de 2 ori, o dată înainte și o dată în timpul apelului constructorului. Primul obiect ind3 va rămâne, astfel, fără referință și ulterior va fi şters de către garbage collector. Referitor la inițializarea datelor (variabile și obiecte) statice, aceasta este similară cu cele nestatice, dacă este plasată la locul de definiţie. Efectul este, însă, diferit, deoarece spațiul de memorare este fix (indiferent de numărul de obiecte create): Curs 1 17 – ordinea de Inițializarea variabilelor inițializare unei clase când există static Output: Curs 1 18 5. Inițializarea variabilelor unei clase – explicații cod; variabile statice Din ieșirea programului se observă că inițializarea statică este efectuată doar atunci când este necesar. Astfel, dacă nu s-ar crea un obiect de tip Echipa și niciodată nu s-ar face referiri de tipul Echipa.j1 sau Echipa.j2, obiectele statice j1 și j2 nu vor fi create. Dacă, însă, sunt create, acest proces are loc o singură dată (la prima creare de obiect de tip Echipa sau la primul acces la obiectul static) Într-un proces de inițializare JAVA se respectă următoarea ordine: obiectele statice (dacă nu au fost inițializate într-un proces anterior de creare de obiect) – deci o singura data obiectele nestatice Curs 1 19 6. Inițializarea masivelor de date Un masiv este o secvență de date de tip primitiv sau de obiecte, de același tip și reunite sub un identificator unic. Operatorul de indexare într-un masiv este [ ], numărul său de apariții fiind egal cu dimensiunea masivului (int a[ ] este un masiv unidimensional, în timp ce int b[ ][ ] este bidimensional). Pentru a defini un masiv este suficientă precizarea tipului, numelui și a operatorului de indexare (exemplu: int[ ] a1; sau int a1[ ];). Observație: Primul tip sintactic este mai sugestiv, el indicând un masiv de întregi – denumit a1. Curs 1 20 6. Inițializarea masivelor de date În momentul definirii unui masiv, compilatorul nu solicită specificarea dimensiunii acestuia - se creează doar o referință la masiv și nu se alocă memorie. Deși la prima vedere par lipsite de sens, instrucțiunile de definire a masivelor în care nu se realizează inițializarea, permit o serie întreagă de atribuiri ce nu implică decât manipulare de referințe. Rezervarea zonei de stocare a masivului se realizează printr-o expresie de inițializare plasată, în principiu, oriunde în codul sursă. Inițializarea simultană cu definirea este efectuată prin precizarea, între acolade, a unui set de valori: int[ ] masiv1={1,2,3,4,5}; Curs 1 21 6. Inițializarea masivelor de date Output: Curs 1 22 6. Inițializarea masivelor de date Masivele de primitive sau obiecte au un membru intrinsec (nu poate fi modificat de programator), ce cuantifică numărul de elemente din masiv: length. Contorizarea elementelor în JAVA (ca și în C și C++) începe cu poziția 0 și, inevitabil, merge până la length-1. Depășirea acestor limite generează o excepție (eroare în faza de rulare). Atunci când elementele unui masiv sunt de tip neprimitiv (obiecte) inițializarea se realizează întotdeauna cu ajutorul cuvântului cheie new; rezultatul va fi generarea unui masiv de referințe Curs 1 23 6. Inițializarea masivelor de date Output: Curs 1 24 6. Inițializarea masivelor de date – explicații cod Primul apel cu new: Integer[ ] a=new Integer[pRand(20)]; creează doar un masiv de referințe. Obiectele masivului sunt create printr-o nouă instrucțiune de inițializare: a[i]=new Integer(pRand(500)); Dacă se ignoră faza de inițializare, tentativa de a citi conținutul unor locații goale va genera o excepție, în faza de rulare. Curs 1 25 7. Inițializarea masivelor de date Inițializarea obiectelor mai poate fi realizată și cu ajutorul seturilor de valori cuprinse între “{}” și separate cu “,” : Integer[ ] b=new Integer[ ] {new Integer(1),new Integer(2),new Integer(3)}; Observație: JAVA extinde adecvat definiția masivelor unidimensionale pentru masivele multidimensionale. De exemplu, o matrice poate fi definită prin următoarea instrucțiune: int[][] matrice={{1,2,3},{4,5,6}}; Curs 1 26