Sunteți pe pagina 1din 24

CAPITOLUL 1 2

INTRODUCERE ÎN UNIVERSUL OBIECTELOR 2

1.1 MODELUL OBIECTUAL 3


1.1.1 CE SUNT OBIECTELE 3
1.1.2 MODELUL OBIECTUAL. ELEMENTE DEFINITORII SPECIFICE 4
1.2 DEFINIREA ŞI CREAREA OBIECTELOR 6
1.2.1 REPREZENTAREA ŞI FORMALIZAREA OBIECTELOR 6
1.2.2 INSTANŢIEREA ŞI INIŢIALIZAREA OBIECTELOR 8
1.3 INTERACŢIUNEA CU ȘI ÎNTRE OBIECTE 20
1.3.1 INVOCAREA ȘI ACCESAREA OBIECTELOR. STRUCTURI DE DATE ORIENTATE OBIECT 20
1.3.2 OPERAŢII, PARAMETRI, METODE ŞI VARIABILE INTERNE 20

1
CAPITOLUL 1
Introducere în universul obiectelor

Înainte de alte explicaţii şi dezbateri mai mult sau mai puţin


academice, fiindcă sintagma cel mai des utilizată este modelul obiectual,
credem că este utilă o clarificare din capul locului a înţelesului cât de cât
formal sau măcar atât cât se poate la acest moment, asupra acestei noţiuni.

Modelul obiectual reprezintă un model de abstractizare şi formalizare


a soluţiilor software la probleme din diverse domenii (în particular şi
domeniul economic), având la bază conceptul de obiect. Domeniul
concret, abstractizat în contextul software, îl vom numi domeniul afacerii,
iar formalizarea acestuia având la bază conceptele legate de obiect o vom
numi modelul orientat obiect al afacerii.

Dincolo de elementele revoluţionare în domeniul proiectării şi


programării pe care le promovează faţă de abordarea structurată,
promotorii modelului obiectual au avut în vedere o deschidere cât mai
largă spre construirea unor structuri cât mai flexibile din punct de vedere
semantic. Prin urmare, pe lângă obiectivul creşterii productivităţii ca
urmare a reutilizării (de la nivelul structurilor conceptuale până la
componentele software concrete), modelul obiectual încearcă să pună la
dispoziţie un „instrumentar” care să compatibilizeze cât mai bine
abstracţiunile din contextul software cu cele din domeniul problemei
reale. De altfel, latura semantică constituie unul din factorii cheie ai
proliferării modelului orientat obiect, în special în sfera problemelor
legate de implementarea a ceea ce generic este indicat prin logica
afacerii, la fel ca și în cazul mediilor vizuale1 care au revoluţionat
dezvoltarea aplicațiilor prin valorificarea orientării lor obiectuale.

1
Prin medii vizuale putem înțelege nu doar instrumente pentru construirea grafică a
interfețelor utilizator, ci inclusiv pentru proiectarea aplicațiilor (vezi instrumentele
CASE) sau asamblarea funcțională a componentelor reutilizabile (un exemplu mai recent
este cadrul de lucru OpenBlocks, http://dspace.mit.edu/handle/1721.1/41550, reîncarnat
în Google App Inventor, http://appinventor.googlelabs.com/about/).
Anexe

1.1 Modelul obiectual


După cum am afirmat deja, modelul obiectual are la bază un concept
ce pare dezarmant de simplu: obiectul. Supra-structurile sintactice şi
semnatice construite pe această bază se pot dovedi însă destul de
complexe. Principiul fundamental al modelării obiectuale constă în
folosirea recursivă a conceptului de obiect, aşa încât „everything is an
object”, inclusiv descrierea formală a obiectelor se bazează tot pe
obiecte2. Acest prim capitol se concentrează în primul rând asupra
lămuririlor privitoare la filosofia obiectelor, în programarea aplicațiilor
bineînțeles, şi asupra modului în care ar trebui să relaţionăm cu ele.

1.1.1 Ce sunt obiectele

O posibilitate de a lămuri ce sunt obiectele, în contextul modelării


orientată obiect a realităţii, ar fi să răspundem mai întâi la o altă întrebare
cu o tentă mai concretă: Ce putem reprezenta folosind obiectele?

Dacă ne gândim însă că, de fapt, obiectele ar constitui elementele


centrale în contextul modelării mai sus-amintite, o formulare mai corectă
a întrebării anterioare ar fi, de fapt, Ce putem abstractiza folosind
obiectele? În acest sens s-ar putea găsi mai multe răspunsuri posibile, de
exemplu:
 o entitate;
 un lucru;
 un concept;
 ceva, care poate fi recunoscut sau delimitabil, ceva de sine
stătător;
 în general, ceva care poate manifesta existenţă independentă;
 orice: „Everything is an object”.

La modul cel mai concret, obiectele sunt caracterizate în primul rând


prin identitate, pentru a putea fi recunoscute şi diferenţiate. Prin urmare
obiectul reprezintă „ceva” identificabil, identitatea fiind caracteristica sa
fundamentală.

A doua întrebare „tulburătoare”, şi poate la fel de relevantă ca și


prima, se referă la: Cum pot fi caracterizate obiectele, în afară de
identitate, despre care deja am amintit? Importanța acestei întrebări
provine din faptul că, pentru a le putea folosi drept blocuri constructive,
obiectele trebuie să aibă:

2
Vezi bibliografie despre reflexie și introspecție în limbajul Java.

3
Anexe

 o anume reprezentare (imagine) în contextul din care fac


parte, cu alte cuvinte să poată fi descrise
 o anumită utilitate, adică să-şi asume anumite responsabilităţi,
să să manifeste anumite comportamente de interes,
 o anumită înclinaţie către socializare, prin urmare posbilitatea
formării de comunităţi de obiecte, cu alte cuvinte obiectele ar
trebui să fie capabile să se manifeste colectiv.

A treia întrebare îndreptăţită spre a lămuri rolul obiectelor ar fi: Ce fac


obiectele?
 se pot asocia, pot forma structuri (compun obiecte de nivel
superior),
 colaborează, pentru a-şi îndeplini responsabilităţile proprii sau
colective.
Cu alte cuvinte, se cunosc: anumite obiecte au cunoştinţă de existenţa
altor obiecte, şi, mai mult, pot comunica între ele, eventual pentru a-şi
cere ajutorul.

Pe parcursul capitolului curent şi, mai ales, a celor ce urmează vom


constata că există mai multe categorii de obiecte sau că obiectele pot fi
caracterizate în mai multe moduri, între care:
 obiecte active şi obiecte pasive;
 obiecte procesate şi obiecte de control (care gestionează
desfăşurarea unui flux de activităţi);
 obiecte entităţi şi obiecte servicii;
 obiecte grafice şi obiecte ale afacerii;
 obiecte generice şi obiecte derivate;
 obiecte simple şi obiecte compuse;
 obiecte persistente şi obiecte tranziente.

1.1.2 Modelul obiectual. Elemente definitorii specifice

Pornind de la modul (sau modelul) de formulare al întrebărilor privind


obiectele din paragraful anterior, modelele obiectuale de reflectare a
problemelor şi soluţiilor se vor baza, după cum vom vedea în particular
în capitolele următoare, pe un „ansamblu” conceptual fundamentat
pornind de la următoarele noţiuni:
1. identitate, pentru a recunoaşte, în special în contextul existenței
mai multor obiecte (de acelaşi fel);
2. stare, constând în suma caracteristicilor sau proprietăţilor
descriptive (informative) şi suma cunoştinţelor (referinţelor) către
alte obiecte;

4
Anexe

3. comportament, modul de manifestare a obiectelor ca urmare a


interacţiunii cu alte obiecte;
4. interacţiuni, pentru a descrie schimbul de mesaje: cereri şi
răspunsuri, în contextul realizării colaborărilor.

Limbajele de modelare orientate obiect, cum este UML3, folosesc


pentru a reprezenta aceste concepte elemente specifice cum ar fi:
1. atribut, proprietate sau caracteristică informaţională a unui obiect;
2. operaţie,
a. sarcină de care poate fi responsabil, ştie să o ducă la
îndeplinire sau ştie să o realizeze, deci o asumă, un obiect;
b. cerere care poate fi adresată, pe care o poate satisface sau
de care poate răspunde un obiect;
3. mesaj, baza comunicării cererilor şi schimbului de informaţii
între obiecte;
4. legătură sau relaţie, cale sau canal de comunicare;
5. navigabilitate, direcţie de comunicare.

Tabelul 1.1 Sumar al cadrului conceptual pe care se fundamentează modelele


orientate obiect
Concepte Limbajul unificat de Limbaje de
fundamentale modelare programare
orientate obiect
Identitate
Stare Atribut Câmp sau variabilă de
instanță
Legătură sau relație și Referință
navigabilitate
Comportament Operație Metodă
Interacțiuni Mesaj Invocare, apel sau
acces

Limbajele de progamare orientate obiect folosesc, pentru a


materializa (sau implementa) aceste concepte, elemente specifice cum ar
fi:
1. câmp sau variabilă de instanţă, pentru materializarea concretă a
unui atribut;
2. metodă, modul de realizare concretă a unei sarcini sau modul de
pregătire concretă a răspunsului la o cerere;
3. invocare, apel sau access, transmiterea concretă a unui mesaj;
4. referinţă, reprezentând un canal de comunicare direct.

3
UML, Unified Modeling Language sau Limbajul unificat de modelare.

5
Anexe

1.2 Definirea şi crearea obiectelor


În paragraful anterior au fost trecute în revistă elementele sau
conceptele fundamentale ale modelului orientat obiect de reprezentare sau
implementare a problemelor şi soluţiilor într-un context computaţional.
Paragraful curent va încerca să expliciteze într-o primă formă aceste
concepte, cu ajutorul sau în cadrul limbajelor de programare orientate
obiect, în particular în cadrul limbajului Java.

1.2.1 Reprezentarea şi formalizarea obiectelor

Îm primul rând, după cum am sugerat deja, cea mai simplă accepțiune
conceptuală a unui obiect ar fi aceea de entitate concretă din domeniul
problemei. În privinţa materializării sau implementării:

 logice, în cadrul limbajului Java obiectul reprezintă o structură


de date (compusă) descrisă printr-o clasă (modul), instanţiată
şi gestionată intern printr-o variabilă ce va stoca referinţa
(pointer) obiectului (sau instanţei);

 fizice, în cadrul mediului de execuției al unei aplicații software


sau mediului runtime, obiectul reprezintă o structură de
memorie gestionată automat într-o zonă de memorie specifică
(heap).

Fundamental în formalizarea obiectelor, în majoritatea limbajelor de


modelare (UML) sau implementare (Java, C#, C++), este conceptul de
clasă. Formal, o clasă reprezintă descrierea unui set de obiecte care
partajează aceleaşi atribute, operaţii, relaţii şi semantică (UML).

Definirea obiectelor prin intermediul claselor comportă însă câteva


nuanţări:

 în modelare, clasa este mai aproape de conceptul de tip, adică


în sensul definiţiei de mai sus: set de obiecte având aceleaşi
caracteristici (expun aceeaşi semantică);

 în privinţa limbajelor de programare, clasele se formează de


fapt dintr-un ansamblu de specificaţii:
 declaraţii de membri atribute şi operaţii;
 blocuri de implementare a operaţiilor sau metode;
 metode de iniţializare a obiectelor sau constructori.

6
Anexe

Pentru a simplifica enunţurile de mai sus, atuci când am


conceptualizat obiectele, am spus că acestea ar trebui să-şi asume un set
de responsabilităţi, de fapt aceste responsabilităţi se vor materializa sub
forma atributelor şi operaţiilor.

O responsabilitate reprezintă o obligaţie, o îndatorire, a obiectelor


unei clase. La nivelul cel mai abstract, atributele şi operaţiile
corespunzătoare unei clase sunt de fapt caracteristicile prin care sunt
realizate sau îndeplinite responsabilităţile obiectelor acesteia:

 un atribut reprezintă o proprietate, calificată prin nume, care


descrie un domeniu (range) de valori ce pot fi reţinute sau
stocate de către instanţele respectivei proprietăţi,

 o operaţie reprezintă definiţia unui serviciu care poate fi cerut


oricărui obiect dintr-o clasă (implementat printr-o metodă
internă, specifică).

// Listing 1.1: Structuri OO din domeniul contabil


//--------------------------------------------------------
public class Cont {
String cod;
String denumire;

// membru static
static String numeOrganizatie;
}
//--------------------------------------------------------
public class InregistrareContabila {
Integer id;
Integer nrOrdine;
String tip; // domeniu legal: debit, credit
Double suma;

// membru referinţă
Cont cont;
}
//--------------------------------------------------------
public class OperatiuneContabila {
String debit = "Debit";
String credit = "Credit";

Integer idOperatiune;

7
Anexe

java.util.Date dataContabilizare;
// membru referinţă multiplicitate > 1
InregistrareContabila[] inregistrari;
}

1.2.2 Instanţierea şi iniţializarea obiectelor

Dacă pentru a reprezenta, defini sau formaliza obiectele am văzut


importanţa conceptului de clasă, crearea şi iniţializarea obiectelor se
realizează printr-un proces numit instanţierea claselor, astfel că
rezultatele acestui proces se numesc generic instanţe, cu alte cuvinte
forma materială a obiectelor într-un univers sau context computaţional.

În limbajul Java, instanţierea unui obiect sau, cu alte cuvinte,


obţinerea unui obiect nou, implică invocarea numelui clasei folosind
cuvântul-cheie new.

// Listing 1.2: Creare obiecte în mediul Java


//--------------------------------------------------------
public class TestCreareObiecte {
public static void main(String[] args){
Cont c_411 = new Cont();

Cont c_401 = new Cont();

InregistrareContabila i1 = new InregistrareContabila();

InregistrareContabila i2 = new InregistrareContabila();

OperatiuneContabila o = new OperatiuneContabila();


}

Odată cu instanţierea unui obiect nou are loc, de regulă, şi


iniţializarea atributelor sau variabilelor de instanţă care formează starea
noului obiect.
Iniţializarea variabilelor de instanţă se face diferenţiat funcţie de:
 natura tipului membrilor: primitive sau non-primitive;
 scopul variabilelor de instanţă: membri statici sau non-statici.

8
Anexe

// Listing 1.3: Iniţializare membri, statici şi non-statici


//--------------------------------------------------------
public class TestCreareObiecte {
public static void main(String[] args){
Cont.numeOrganizatie = "Gama SA";
Cont c_411 = new Cont();
c_411.cod = "411";
c_411.denumire = “Clienti";
System.out.println(c_411.getClass() + “: c_411 [" +
c_411.cod + “, “ + c_411.denumire
+ “, “ + c_411.numeOrganizatie + “]");

Cont c_401 = new Cont();


c_401.cod = “401";
c_401.denumire = “Furnizori";
System.out.println(c_401.getClass() + “: c_401 [" +
c_401.cod + “, “ + c_401.denumire
+ “, “ + c_401.numeOrganizatie + “]");

InregistrareContabila i1 = new InregistrareContabila();


i1.id = 1;
i1.nrOrdine = 1;
i1.tip = “Debit";
i1.suma = 120.0;
System.out.println(i1.getClass() + “: i1 [" +
i1.id + “, “ + i1.tip + “, “ + i1.suma + “]");

InregistrareContabila i2 = new InregistrareContabila();


i2.id = 2;
i2.nrOrdine = 1;
i2.tip = “Credit";
i2.suma = 120.0;
System.out.println(i2.getClass() + “: i2 [" +
i2.id + “, “ + i2.tip + “, “ + i2.suma + “]");

OperatiuneContabila o = new OperatiuneContabila();


o.idOperatiune = 1;
o.dataContabilizare = new java.util.Date();// data curenta
System.out.println(o.getClass() + “: o [" +
o.idOperatiune + “, “ +
o.dataContabilizare + “]");
}
}

9
Anexe

În Java, iniţializarea implicită respectă următoarele reguli:

 membrii primitivi sunt iniţializaţi: cu 0 pentru primitive


numerice, cu 0 sau spaţiu pentru primitive char, cu false
pentru primitive boolean;

 membrii referinţe sunt inițializați astfel încât le va fi rezervată


zona de memorie necesară pentru stocarea referințelor către
alte obiecte, fără însă a se obține și o referință efectivă,
obișnuindu-se să se afirme că sunt inițializați „cu null”.

// Listing 1.4: Iniţializare membrii primitivi vs. referinţe


//--------------------------------------------------------
public class TestCreareObiecte {
public static void main(String[] args){
Cont.numeOrganizatie = “Gama SA";
Cont c_411 = new Cont();
c_411.cod = “411";
c_411.denumire = “Clienti";
System.out.println(c_411.getClass() + “: c_411 [" +
c_411.cod + “, “ + c_411.denumire
+ “, “ + c_411.numeOrganizatie + “]");

Cont c_5121 = new Cont();


c_5121.cod = “5121";
c_5121.denumire = “Cont banca";
System.out.println(c_5121.getClass() + “: c_401 [" +
c_5121.cod + “, “ + c_5121.denumire
+ “, “ + c_5121.numeOrganizatie + “]");

InregistrareContabila i1 = new InregistrareContabila();


i1.id = 1;
i1.nrOrdine = 1;
i1.tip = “Debit";
i1.suma = 120.0;
System.out.println(i1.getClass() + “: i1 inainte [" +
i1.id + “, “ + i1.tip + “, “ +
i1.cont + “, “ + i1.suma + “]");
i1.cont = c_411;
System.out.println(i1.getClass() + “: i1 dupa [" +
i1.id + “, “ + i1.tip + “, “ +
i1.cont.cod + “, “ + i1.suma + “]");

InregistrareContabila i2 = new InregistrareContabila();

10
Anexe

i2.id = 2;
i2.nrOrdine = 1;
i2.tip = “Credit";
i2.suma = 120.0;
System.out.println(i2.getClass() + “: i2 inainte [" +
i2.id + “, “ + i2.tip + “, “ +
i2.cont + “, “+ i2.suma + “]");
i2.cont = c_5121;
System.out.println(i2.getClass() + “: i2 dupa [" +
i2.id + “, “ + i2.tip + “, “ +
i2.cont.cod + “, “+ i2.suma + “]");

OperatiuneContabila o = new OperatiuneContabila();


o.idOperatiune = 1;
o.dataContabilizare = new Date(); // data curenta
System.out.println(o.getClass() + ": o ["
+ o.idOperatiune + “, “
+ o.dataContabilizare + “]");
}
}
//--------------------------------------------------------
Rezultat:
//--------------------------------------------------------
class app.model.contabilitate.Cont: c_411 [411, Clienti, Gama SA]
class app.model.contabilitate.Cont: c_401 [5121, Cont banca, Gama
SA]
class app.model.contabilitate.InregistrareContabila: i1 inainte
[1, Debit, null, 120.0]
class app.model.contabilitate.InregistrareContabila: i1 dupa [1,
Debit, 411, 120.0]
class app.model.contabilitate.InregistrareContabila: i2 inainte
[2, Credit, null, 120.0]
class app.model.contabilitate.InregistrareContabila: i2 dupa [2,
Credit, 5121, 120.0]
class app.model.contabilitate.OperatiuneContabila: o [1, Sun Jan
10 17:22:59 EET 2010]

Iniţializarea explicită a membrilor referinţe se referă la instanţierea


obiectelor în procesul de iniţializare a variabilelor de instanţă. În mod
practic, două condiţii trebuie îndeplinite:
 crearea unei metode-constructor care să preia drept argumente
valorile ce vor fi utilizate pentru iniţializarea explicită;

11
Anexe

 utilizarea declaraţiei new în felul următor:


nume_var_ref = new NumeClasă(argumente);

// Listing 1.5: Iniţializare explicită


// membrii primitivi vs. referinţe

//--------------------------------------------------------
public class Cont {
String cod;
String denumire;

static String numeOrganizatie;

public Cont() {
}

public Cont(String cod, String denumire) {


this.cod = cod;
this.denumire = denumire;
}
}
//--------------------------------------------------------
public class InregistrareContabila {
Integer id;
Integer nrOrdine;
String tip; // debit, credit
Double suma;

Cont cont;

public InregistrareContabila() {
}

public InregistrareContabila(Integer id,


Integer nrOrdine, String tip,
Double suma, Cont cont) {
this.id = id;
this.nrOrdine = nrOrdine;
this.tip = tip;
this.suma = suma;
this.cont = cont;
}

//--------------------------------------------------------

12
Anexe

public class OperatiuneContabila {


static String debit = “Debit";
static String credit = “Credit";

Integer idOperatiune;
Date dataContabilizare;

InregistrareContabila[] inregistrari;

public OperatiuneContabila() {
}
public OperatiuneContabila(Integer idOperatiune,
Date dataContabilizare,
InregistrareContabila[] inregistrari) {
this.idOperatiune = idOperatiune;
this.dataContabilizare = dataContabilizare;
this.inregistrari = inregistrari;
}
}

//--------------------------------------------------------
public class TestCreareObiecte2 {
public static void main(String[] args){
Cont.numeOrganizatie = “Gama SA";
Cont c_411 = new Cont("411", “Clienti");
System.out.println(c_411.getClass() + “: c_411 [" +
c_411.cod + “, “ + c_411.denumire
+ “, “ + c_411.numeOrganizatie + “]");

Cont c_5121 = new Cont("5121", “Cont banca");


System.out.println(c_5121.getClass() + “: c_401 [" +
c_5121.cod + “, “ + c_5121.denumire
+ “, “ + c_5121.numeOrganizatie + “]");

InregistrareContabila i1 = new InregistrareContabila(1, 1,


“Debit", 120.0, c_411);
System.out.println(i1.getClass() + “: i1 [" +
i1.id + “, “ + i1.tip + “, “ +
i1.cont.cod + “, “ + i1.suma + “]");

InregistrareContabila i2 = new InregistrareContabila(1, 1,


“Credit", 120.0, c_5121);
System.out.println(i2.getClass() + “: i2 [" +

13
Anexe

i2.id + “, “ + i2.tip + “, “ +
i2.cont.cod + “, “+ i2.suma + “]");

OperatiuneContabila o =
new OperatiuneContabila(1, new Date(), null);
System.out.println(o.getClass() + “: o [" +
o.idOperatiune + “, “ + o.dataContabilizare + “]");
}
}

În structura unui obiect, din punct de vedere conceptual, un membru-


variabilă de instanţă este caracterizat şi prin multiplicitate (pe lîngă nume
şi tip, aşa cum am arătat mai sus). Practic vorbind, în cazul limbajului
Java, atunci când un membru-variabilă de instanţă trebuie să gestioneze
mai multe valori de acelaşi tip, ceea ce înseamnă că din punct de vedere
conceptual este vorba de o multiplicitate > 1, atunci, varianta cea mai
directă presupune că acel membru va fi de fapt de tip array.

Folosirea tablourilor pentru membri cu mutiplicitate > 1

Declararea unui membru de tip array în limbajul Java presupune


adăugarea, fie la numele membrului, fie la tipul acestuia, a simbolurilor
specifice [ și ]:
NumeTip [] numeTablou; // sau
NumeTip numeTablou[];

În fapt, un tablou este o instanţă, un obiect, provenit dintr-o clasă


care permite gestionarea indexată a mai multor valori de acelaşi tip.
Pentru aflarea dimensiunii (numărului de elemente) tablourile prezintă
proprietatea intrinsecă length.

Procesul de iniţializare a unui tablou presupune următoarele etape:


 iniţializarea tabloului „în sine” - în această etapă va fi
specificat numărul de elemente care vor forma tabloul, şi-
 iniţializarea elementelor care formează tabloul (sau rubricilor
tabloului).

// Listing 1.5: Exemplu iniţializare tablou


//--------------------------------------------------------
public class TestCreareObiecte3 {
public static void main(String[] args){

14
Anexe

Cont.numeOrganizatie = “Gama SA";


Cont c_411 = new Cont("411", “Clienti");
Cont c_5121 = new Cont("5121", “Cont banca");

// Declarare tablou
InregistrareContabila[] inregistrariContabile;

// Iniţializare tablou
inregistrariContabile = new InregistrareContabila[2];

// Iniţializare explicită a elementelor


inregistrariContabile[0] = new InregistrareContabila(1, 1,
“Debit", 120.0, c_411);
inregistrariContabile[1] = new InregistrareContabila(1, 1,
“Credit", 120.0, c_5121);

OperatiuneContabila o =
new OperatiuneContabila(1,
new Date(), inregistrariContabile);

System.out.println(o.getClass() + “: o [" +
o.idOperatiune + “, “ + o.dataContabilizare + “, “ +
o.inregistrari.length + “]");
}
}
//--------------------------------------------------------
Rezultat:
//--------------------------------------------------------
class app.model.contabilitate.OperatiuneContabila: o [1, Sun Jan
10 17:41:24 EET 2010, 2]

Sintaxa limbajului Java, permite reprezentarea procesului de


iniţializare în două moduri:
1) iniţializarea separată a tabloului şi a elementelor, vezi exemplul de
mai sus;
2) iniţializarea în aceeaşi instrucţiune a tabloului şi elementelor, vezi
exemplul care urmează.

// Listing 1.6: Rafinare iniţializare tablou

//-------------Varianta 1 -----------------------------
public class TestCreareObiecte4 {
public static void main(String[] args){
Cont.numeOrganizatie = „Gama SA";

15
Anexe

Cont c_411 = new Cont("411", „Clienti");


Cont c_5121 = new Cont("5121", „Cont banca");

InregistrareContabila[] inregistrariContabile =
{
new InregistrareContabila(1, 1,"Debit", 120.0, c_411),
new InregistrareContabila(2, 1,"Credit", 120.0, c_5121)
};

OperatiuneContabila o =
new OperatiuneContabila(1, new Date(),
inregistrariContabile);

System.out.println(o.getClass() + „: o [" +
o.idOperatiune + „, „ + o.dataContabilizare + „, „ +
o.inregistrari.length + „]");

// parcurgere elemente tablou


for (InregistrareContabila i : o.inregistrari){
System.out.println(i.getClass() + „: i [" +
i.id + „, „ + i.tip + „, „ +
i.cont.cod + „, „+ i.suma + „]");
}
}
}
//-------------Varianta 2 -----------------------------
public class TestCreareObiecte5 {
public static void main(String[] args){
Cont.numeOrganizatie = „Gama SA";
Cont c_411 = new Cont("411", „Clienti");
Cont c_5121 = new Cont("5121", „Cont banca");

OperatiuneContabila o =
new OperatiuneContabila(1, new Date(),
new InregistrareContabila[]{
new InregistrareContabila(1, 1,"Debit",
120.0, c_411),
new InregistrareContabila(2, 1,
"Credit", 120.0, c_5121)
}
);

System.out.println(o.getClass() + „: o [" +
o.idOperatiune + „, „ + o.dataContabilizare + „, „ +

16
Anexe

o.inregistrari.length + „]");
// parcurgere elemente tablou
for (int i = 0; i < o.inregistrari.length; i++){
System.out.println(o.inregistrari[i].getClass() +
": i" + i + „ [" + o.inregistrari[i].id +
", „ + o.inregistrari[i].tip + „, „ +
o.inregistrari[i].cont.cod +
", „+ o.inregistrari[i].suma + „]");
}
}
}

Folosirea colecţiilor pentru membri cu mutiplicitate > 1

În limbajul Java, de altfel şi în alte limbaje consacrate orientate obiect,


tablourile au avantajul integrării lor în sintaxa limbajului. Ele au însă şi
dezavantaje destul de importante, dintre care putem sublinia cel puţin
imposibilitatea re-dimesionării dinamice. Aceste dezavantaje au fost
depăşite, într-un anume fel, folosind colecţiile pentru gestiunea comună a
unui grup de valori, primitive sau referinţe, în locul tablourilor.

De exemplu, colecţia List, implementată concret prin clasa ArrayList,


are următoarele caracteristici marcate printr-un set de operații specifice:
 posibilitatea aflării numărului de elemente din listă: size();
 posibilitatea verificării iniţializării cu elemente concrete a listei:
isEmpty();
 posibilitatea accessului la elemente individuale:
o obținerea elementului de pe o poziție dată, get(indexNN);
o stocarea referinței unui obiect ca un element situat pe o
poziție dată, set(indexNN, element);
o ștergerea din colecție a referinței unui obiect de la o poziție
dată, remove(indexNN);
o poziția concretă în colecție a referinței unui obiect dat,
indexOf(element);
 conversie într-o structură clasică de tip tablou:
o toArray().

Structura de control repetitivă necesară parcurgerii elementelor unei


colecții provine din clasica structură for adaptată specific astfel:
for(Tip numeVarIterati : numeList) {... ...}

17
Anexe

// Listing 1.7: Exemplu iniţializare listă


//--------------------------------------------------------
public class OperatiuneContabila {
static String debit = „Debit";
static String credit = „Credit";

Integer idOperatiune;
Date dataContabilizare;

List<InregistrareContabila> inregistrari =
new ArrayList<InregistrareContabila>();
// fata de: InregistrareContabila[] inregistrari

public OperatiuneContabila() {
}

public OperatiuneContabila(Integer idOperatiune,


Date dataContabilizare,
List<InregistrareContabila> inregistrari) {
this.idOperatiune = idOperatiune;
this.dataContabilizare = dataContabilizare;
this.inregistrari = inregistrari;
}
}
//--------------------------------------------------------
public class TestCreareObiecte_6 {
public static void main(String[] args){
Cont.numeOrganizatie = „Gama SA";
Cont c_411 = new Cont("411", „Clienti");
Cont c_5121 = new Cont("5121", „Cont banca");

List<InregistrareContabila> inregistratiContabile =
new ArrayList<InregistrareContabila>();
inregistratiContabile.add(new InregistrareContabila(1,
1,"Debit", 120.0, c_411));
inregistratiContabile.add(new InregistrareContabila(2,
1,"Credit", 120.0, c_5121));

OperatiuneContabila o =
new OperatiuneContabila(1,
new Date(),inregistratiContabile);

System.out.println(o.getClass() + „: o [" +
o.idOperatiune + „, „ + o.dataContabilizare +

18
Anexe

", „ + o.inregistrari.size() + „]");


for (InregistrareContabila i : o.inregistrari){
System.out.println(i.getClass() + „: i [" +
i.id + „, „ + i.tip + „, „ +
i.cont.cod + „, „+ i.suma + „]");
}
}
}

19
Anexe

1.3 Interacţiunea cu și între obiecte


În continuare vom încerca să lămurim rolul obiectelor în execuţia
aplicaţiilor, mai exact modul în care se efectuează apelul sau invocarea
obiectelor.

1.3.1 Invocarea și accesarea obiectelor. Structuri de date


orientate obiect

În general, execuţia unei aplicaţii reprezintă set de apeluri de funcţii şi


proceduri. Execuţia unei aplicaţii cu obiecte poate fi văzută ca un set de
interacţiuni între un grup/comunitate de obiecte.

Prin interacţiune se înţelege de fapt apelul (sincron sau asicron) al


operaţiilor asociate obiectelor.

Invocarea operaţiilor se realizează prin adresare către (prin


intermediul) obiectele (obiectelor) de care aparţin. Concret, în cazul
aplicaţiilor scrise în limbajul Java invocarea obiectelor se circumscrie în
mare sintaxei, aşa-zise „cu punct”:
sintaxa cu punct: obiect.operaţie (listă argumente)

Invocarea aceleaşi operaţii către obiecte distincte poate conduce la


rezultate distincte: execuţia operaţiei se face în contextul de stare distinct,
propriu fiecărui obiect.
Invocarea operaţiilor presupune anumite pre-condiţii:
 mai întâi trebuie să existe obiectele: obiectele trebuie
instanţiate;
 obiectele trebuie să fie adresabile (să poată fi accesate
referinţele lor în contextul din care vor fi invocate);
 obiectele trebuie să prezinte operaţii invocabile (vizibile).

1.3.2 Operaţii, parametri, metode şi variabile interne

După cum am arătat deja, semnătura operaţiilor, cel puţin în cazul


limbajului Java, presupune următoarele specificaţii privind:
 numele şi tipul returnat;
 specificatori de vizibilitate;
 parametrizarea.

20
Anexe

Metodele reprezintă formal blocuri de instrucţiuni care:

 pe de o parte descriu algoritmul despre cum anume concret sau


funcţional, se comportă un obiect invocat prin numele unei
operaţii;

 pe de altă parte sunt executate ca urmare a invocării operaţiilor


cărora îi este ataşate ca specificaţii de implemenare.

De multe ori termenii de operație și metodă sunt folosiți inter-


schimbabil. Cu preponderenţă în contextul claselor se foloseşte termenul
metode, iar în contextul interfeţelor se foloseşte termenul operaţii. Aceștia
reprezintă totuși concepte diferite, operația reprezintă doar o specificație
de interacțiune, formatul mesajelor de interacțiune, iar metodele
reprezintă formele concrete de re-acțiune a obiectelor la aceste mesaje. Pe
scurt, spunem că metodele reprezintă implementarea operaţiilor.

Structurilele specifice care pot forma blocul de instrucţiuni ce


concretizează o metodă constau în:

 structuri de date:
 variabile interne;
 invocarea variabilelor de instanţă, declarate la nivelul
clasei;
 parametri;

 structuri de control:
 alternative, simple sau generalizate;
 repetitive;
 recursive.

// Listing 1.8: Sintaxa structurilor specifice limbajului Java

if (<expr-booleană>){
<bloc de instrucţiuni>
} else if {
<bloc de instrucţiuni>
} else {
<bloc de instrucţiuni>
}// end if -------------------------------------

switch <expresie evaluabilă la valori int sau Integer>{


case <valoare int/Integer> : {

21
Anexe

<bloc de instrucţiuni>
} break;
case <valoare int/Integer> : {
<bloc de instrucţiuni>
} break; // in lipsă va continua şi evaluarea
// celorlalte ramuri introduse prin valori int/Integer
.. ... ...
default <valoare int/Integer> : {
<bloc de instrucţiuni>
} break;
}// end switch -------------------------------------

while (<expr-booleană>) {
<bloc de instrucţiuni>
break; // părăsire bloc while
continue; // salt la iteraţia următoare
<bloc de instrucţiuni>
}// end while -------------------------------------

for (<iniţializare increment>;


<expr-booleană>; <expr-incrementare>){
<bloc de instrucţiuni>
break;
continue;
<bloc de instrucţiuni>
}// end for simplu -------------------------------------

for (<iniţializare var parcurgere elemente> :


<nume tablou sau colecţie>){
<bloc de instrucţiuni>
break;
continue;
<bloc de instrucţiuni>
}// end for parcurgere colecţie ------------------------

Un tip de metode speciale, care nu sunt asociate în mod concret unei


operaţii explicite, al cărui nume este de fapt numele clasei, sunt metodele
constructor. Nefiind reprezentarea unei operaţii, care eventual ar putea
face parte din specificația unei interfețe, invocarea unui constructor se
face prin cuvântul cheie new şi numele clasei.

22
Anexe

// Listing 1.9: Exemplu iniţializare listă


//-------------------------------------------------------

public class ServiciuOperatiuni {


//declaratie operatie
public Double getSold(OperatiuneContabila o)
{ // start metoda implementare operaţie
return getDebit(o) - getCredit(o);
} // sfârşit metoda implementare operaţie

public Double getDebit(OperatiuneContabila o //parametru ){


Double debit = 0.0; // variabila internă
for (InregistrareContabila i: o.inregistrari){
if (i.tip == OperatiuneContabila.debit)
debit += i.suma;
}
return debit;
}

public Double getCredit(OperatiuneContabila o){


Double credit = 0.0;
for (InregistrareContabila i: o.inregistrari){
if (i.tip == OperatiuneContabila.debit)
credit += i.suma;
}
return credit;
}
}
//--------------------------------------------------------
public class TestCreareObiecte_7 {
public static void main(String[] args){
Cont.numeOrganizatie = „Gama SA";
Cont c_411 = new Cont("411", „Clienti");
Cont c_5121 = new Cont("5121", „Cont banca");

List<InregistrareContabila> inregistratiContabile =
new ArrayList<InregistrareContabila>();
inregistratiContabile.add(
new InregistrareContabila(1, 1,
"Debit", 120.0, c_411));
inregistratiContabile.add(
new InregistrareContabila(2, 1,
"Credit", 120.0, c_5121));

23
Anexe

OperatiuneContabila o =
new OperatiuneContabila(1, new Date(),
inregistratiContabile);

ServiciuOperatiuni s = new ServiciuOperatiuni();


Double sold = s.getSold(o); // invocare operatie

System.out.println(o.getClass() + „: o [" +
o.idOperatiune + „, „ + o.dataContabilizare +
", „ + „sold = „ + sold + „]");
for (InregistrareContabila i : o.inregistrari){
System.out.println(i.getClass() + „: i [" +
i.id + „, „ + i.tip + „, „ +
i.cont.cod + „, „+ i.suma + „]");
}
}
}
//--------------------------------------------------------
Rezultat
//--------------------------------------------------------
class app.model.contabilitate.OperatiuneContabila: o [1, Sun Jan
10 18:27:19 EET 2010, sold = 0.0]
class app.model.contabilitate.InregistrareContabila: i [1, Debit,
411, 120.0]
class app.model.contabilitate.InregistrareContabila: i [2, Credit,
5121, 120.0]

24

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