3.1 Obiecte d9o20ok
3.2 Incapsularea informatiilor in interiorul obiectelor
3.3 Clase de obiecte
3.4 Derivarea claselor de obiecte
3.5 Interfete spre obiecte
3.1 Obiecte
Informatiile pe care le reprezentam in memoria calculatorului sunt rareori
atat de simple precum culorile sau literele. In general, dorim sa reprezentam
informatii complexe, care sa descrie obiectele fizice care ne inconjoara sau
notiunile cu care operam zilnic, in interiorul carora culoarea sau o secventa
de litere reprezinta doar o mica parte. Aceste obiecte fizice sau notiuni din
lumea reala trebuiesc reprezentate in memoria calculatorului in asa fel incat
informatiile specifice lor sa fie pastrate la un loc si sa se poata prelucra
ca un tot unitar. Sa nu uitam insa ca, la nivelul cel mai de jos, informatia
atasata acestor obiecte continua sa fie tratata de catre compilator ca un sir
de numere naturale, singurele informatii reprezentabile direct in memoria calculatoarelor
actuale.
Pentru a reprezenta in memoria interna obiecte fizice sau notiuni, este nevoie
sa izolam intregul set de proprietati specifice acestora si sa il reprezentam
prin numere. Aceste numere vor ocupa in memorie o zona compacta pe care, printr-un
abuz de limbaj, o vom numi, intr-o prima aproximare, obiect. Va trebui
insa sa aveti intotdeauna o imagine clara a deosebirii fundamentale dintre un
obiect fizic sau o notiune si reprezentarea acestora in memoria calculatorului.
De exemplu, in memoria calculatorului este foarte simplu sa cream un nou obiect,
identic cu altul deja existent, prin simpla duplicare a zonei de memorie folosite
de obiectul pe care dorim sa-l dedublam. In realitate insa, este mult mai greu
sa obtinem o copie identica a unui obiect fizic, fie el o simpla foaie de hartie
sau o bancnota de 10000 de lei.
Sa revenim insa la numerele naturale. Din moment ce ele sunt singurele entitati
reprezentabile in memoria calculatorului, este firesc ca acesta sa fie echipat
cu un set bogat de operatii predefinite de prelucrare a numerelor. Din pacate,
atunci cand facem corespondenta dintre numere si litere de exemplu, nu ne putem
astepta la un set la fel de bogat de operatii predefinite care sa lucreze cu
litere. Dar, tinand cont de faptul ca in cele din urma lucram tot cu numere,
putem construi propriile noastre operatii specifice literelor, combinand in
mod corespunzator operatiile numerice predefinite.
De exemplu, pentru a obtine dintr-o litera majuscula, sa spunem 'A', corespondenta
ei minuscula 'a', este suficient sa adunam un deplasament numeric corespunzator,
presupunand ca literele mari si cele mici sunt numerotate in ordine alfabetica
si imediat una dupa cealalta in conventia de reprezentare folosita. In setul
ASCII deplasamentul este 32, reprezentarea lui 'A' fiind 65 iar reprezentarea
lui 'a' fiind 97. Acest deplasament se pastreaza pentru toate literele din alfabetul
englez si roman, la cel din urma existand totusi o exceptie in cazul literei
'S'.
Putem sa extindem cerintele noastre mai departe, spunand ca, atunci cand analizam
un obiect fizic sau o notiune pentru a le reprezenta in calculator, trebuie
sa analizam nu numai proprietatile acestora dar si modul in care acestea pot
fi utilizate si care sunt operatiile care pot fi executate asupra lor sau cu
ajutorul lor. Acest set de operatii va trebui ulterior sa-l redefinim in contextul
multimii de numere care formeaza proprietatile obiectului din memoria calculatorului,
si sa il descompunem in operatii numerice preexistente. In plus, trebuie sa
analizam modul in care reactioneaza obiectul atunci cand este supus efectului
unor actiuni exterioare. Uneori, setul de operatii specifice unui obiect impreuna
cu modul in care acesta reactioneaza la stimuli exteriori se numeste comportamentul
obiectului.
De exemplu, daca dorim sa construim un obiect care reprezinta o minge de forma
sferica in spatiu, este necesar sa definim trei numere care sa reprezinte coordonatele
x, y si z relativ la un sistem de axe dat, precum si o valoare pentru raza sferei.
Aceste valori numerice vor face parte din setul de proprietati ale obiectului
minge. Daca mai tarziu vom dori sa construim o operatie care sa reprezinte mutarea
in spatiu a obiectului minge, este suficient sa ne folosim de operatiile cu
numere pentru a modifica valorile coordonatelor x, y si z.
Desigur, obiectul minge este insuficient descris prin aceste coordonate si,
pentru a simula in calculator obiectul real este nevoie de multe proprietati
suplimentare precum si de multe operatii in plus. Dar, daca problema pe care
o avem de rezolvat nu necesita aceste proprietati si operatii, este preferabil
sa nu le definim in obiectul folosit pentru reprezentare. Rezultatul direct
al acestui mod de abordare este acela ca vom putea defini acelasi obiect real
in mai multe feluri pentru a-l reprezenta in memoria interna. Modul de definire
depinde de problema de rezolvat si de programatorul care a gandit reprezentarea.
De altfel, aceste diferente de perceptie ale unui obiect real exista si intre
diversi observatori umani.
Din punctul de vedere al programarii, un obiect este o reprezentare in memoria
calculatorului a proprietatilor si comportamentului unei notiuni sau ale unui
obiect real.
/cap3_01.gif)
Figura 3.1 Modelul de reprezentare al unui obiect in memorie.
Stratul exterior reprezinta doar operatiile care ofera calea de a interactiona
cu proprietatile obiectului si nu are corespondent direct in zona de memorie
ocupata de obiect. /sus.gif)
3.2 Incapsularea informatiilor in interiorul obiectelor
Exista situatii in care accesul din exterior la proprietatile unui obiect poate
sa puna probleme acestuia. Ce s-ar intampla de exemplu daca s-ar putea accesa
direct valorile care definesc functionalitatea corpului uman? Desigur, exista
cazuri in care acest lucru ar fi imbucurator. N-ar mai fi nevoie sa actionam
indirect asupra concentratiilor de enzime in corp ci am putea sa modificam aceste
valori in mod direct. Dar, in acelasi timp, am putea provoca mari necazuri in
cazul in care am modifica aceste valori in afara pragului suportabil de catre
organism. Din aceste motive, este preferabil sa lasam modificarea acestor parametri
in sarcina exclusiva a unor operatii definite de catre obiect, operatii care
vor verifica noile valori inainte de a le schimba in interiorul obiectului.
In lipsa acestui filtru, putem sa stricam coerenta valorilor memorate in interiorul
unui obiect, facandu-l inutilizabil.
Din acest punct de vedere, putem privi obiectul ca pe un set de valori care
formeaza miezul obiectului si un set de operatii care imbraca aceste valori,
protejandu-le. Vom spune ca proprietatile obiectului sunt incapsulate
in interiorul acestora. Mai mult, obiectul incapsuleaza si modul de functionare
a operatiilor lui specifice, din exterior neputandu-se observa decat modul de
apelare a acestor operatii si rezultatele apelurilor. Cu alte cuvinte, procesul
de incapsulare este procesul de ascundere a detaliilor neimportante sau
sensibile de constructie a obiectului.
Dar nu numai proprietatile unui obiect trebuiesc protejate ci si operatiile
definite de catre acesta. Unele dintre operatiile definite pentru un obiect,
cum ar fi de exemplu procesul respirator al omului, sunt periculos de lasat
la dispozitia oricui. Este preferabil sa putem controla foarte exact cine ce
operatii poate apela pentru un anumit obiect. In acest mod, din punctul de vedere
al unui observator strain, omul este perceput ca un obiect mult mai simplu decat
este in realitate, pentru ca acel observator nu poate vedea decat acele valori
si nu poate apela decat acele operatii care sunt facute publice.
Desigur, in practica este nevoie de o oarecare rafinare a gradului de protejare
a fiecarei operatii sau proprietati in asa fel incat insusi accesul observatorilor
exteriori sa poata fi nuantat in functie de gradul de similitudine si apropiere
al observatorului fata de obiectul accesat. Rafinarea trebuie sa mearga pana
la a putea specifica pentru fiecare proprietate si operatie in parte care sunt
observatorii care au acces si care nu.
Aceasta protejare si incapsulare a proprietatilor si operatiilor ce se pot
executa cu ajutorul unui obiect are si o alta consecinta si anume aceea ca utilizatorul
obiectului respectiv este independent de detaliile constructive ale obiectului
respectiv. Structura interna a obiectului poate fi astfel schimbata si perfectionata
in timp fara ca functionalitatea de baza sa fie afectata. /sus.gif)
3.3 Clase de obiecte
In lumea reala se pot identifica usor familii de obiecte. Este greu sa descriem
intr-un limbaj de programare fiecare minge din lume dar, pentru a putea folosi
orice minge din lume, este suficient sa descriem o singura data care sunt proprietatile
unei mingi in general, precum si operatiile care pot fi executate cu aceasta.
Aceasta nu inseamna ca toate obiectele minge din lume sunt identice. Diferenta
dintre ele se afla reprezentata in primul rand in valorile proprietatilor lor
care sunt marimi numerice variabile, adica difera de la un obiect de acelasi
fel la altul. De exemplu, in fiecare obiect minge vom avea un numar natural
care reprezinta culoarea mingii. Acest numar poate sa difere de la o minge la
alta exact asa cum, in realitate, culoarea difera de la o minge la alta. La
fel coordonatele pozitiei mingii la un moment dat sau raza mingii precum si
materialul din care este confectionata au valori care variaza de la o minge
la alta.
Cu alte cuvinte, fiecare minge din lume are acelasi set de proprietati, dar
valorile acestora pot sa difere de la o minge la alta. Modelul de reprezentare
in memorie a unui obiect este intotdeauna acelasi, dar valorile memorate in
locatiile corespunzatoare proprietatilor sunt in general diferite.
In ceea ce priveste operatiile, acestea sunt intotdeauna aceleasi dar rezultatul
aplicarii lor poate sa difere in functie de valorile proprietatilor obiectului
asupra caruia au fost aplicate. De exemplu, atunci cand aruncam o minge spre
pamant ea va ricosa din acesta ridicandu-se din nou in aer. Inaltimea la care
se va ridica insa, este dependenta de dimensiunile si materialul din care a
fost confectionata mingea. Cu alte cuvinte, noua pozitie in spatiu se va calcula
printr-o operatie care va tine cont de valorile memorate in interiorul obiectului.
Se poate intampla chiar ca operatia sa hotarasca faptul ca mingea va strapunge
podeaua in loc sa fie respinsa de catre aceasta.
Sa mai observam ca operatiile nu depind numai de proprietatile obiectului ci
si de unele valori exterioare acestuia. Atunci cand aruncam o minge spre pamant,
inaltimea la care va ricosa aceasta depinde si de viteza cu care a fost aruncata
mingea. Aceasta viteza este un parametru al operatiei de aruncare. Nu are nici
un rost sa transmitem ca parametrii ai unei operatii valorile proprietatilor
unui obiect pentru ca acestea sunt intotdeauna disponibile operatiei. Nici o
operatie nu se poate aplica asupra unui obiect fara sa stim exact care este
obiectul respectiv si ce proprietati are acesta. Este absurd sa ne gandim la
ce inaltime se va ridica o minge in general, fara sa facem presupuneri asupra
valorilor proprietatilor acesteia. Sa mai observam insa ca, daca toate mingile
ar avea aceleasi valori pentru proprietatile implicate in operatia descrisa
mai sus, am putea sa calculam inaltimea de ricoseu in general, fara sa fim dependenti
de o anumita minge.
In concluzie, putem spune ca obiectele cu care lucram fac parte intotdeauna
dintr-o familie mai mare de obiecte cu proprietati si comportament similar.
Aceste familii de obiecte le vom numi in continuare clase de obiecte
sau concepte in timp ce obiectele apartinand unei anumite clase le vom
numi instante ale clasei de obiecte respective. Putem vorbi despre clasa
de obiecte minge si despre instantele acesteia, multimea tuturor obiectelor
minge care exista in lume. Fiecare instanta a clasei minge are un loc bine precizat
in spatiu si in timp, un material si o culoare. Aceste proprietati difera de
la o instanta la alta, dar fiecare instanta a aceleiasi clase va avea intotdeauna
aceleasi proprietati si aceleasi operatii vor putea fi aplicate asupra ei. In
continuare vom numi variabile aceste proprietati ale unei clase de obiecte
si vom numi metode operatiile definite pentru o anumita clasa de obiecte.
Pentru a clarifica, sa mai reluam inca o data: O clasa de obiecte este o descriere
a proprietatilor si operatiilor specifice unui nou tip de obiecte reprezentabile
in memorie. O instanta a unei clase de obiecte este un obiect de memorie care
respecta descrierea clasei. O variabila a unei clase de obiecte este o proprietate
a clasei respective care poate lua valori diferite in instante diferite ale
clasei. O metoda a unei clase este descrierea unei operatii specifice clasei
respective.
Sa mai precizam faptul ca, spre deosebire de variabilele unei clase, metodele
acesteia sunt memorate o singura data pentru toate obiectele. Comportarea diferita
a acestora este data de faptul ca ele depind de valorile variabilelor.
O categorie aparte a claselor de obiecte este categoria acelor clase care reprezinta
concepte care nu se pot instantia in mod direct, adica nu putem construi instante
ale clasei respective, de obicei pentru ca nu avem destule informatii pentru
a le putea construi. De exemplu, conceptul de om nu se poate instantia in mod
direct pentru ca nu putem construi un om despre care nu stim exact daca este
barbat sau femeie. Putem in schimb instantia conceptul de barbat si conceptul
de femeie care sunt niste subconcepte ale conceptului om.
Clasele abstracte, neinstantiabile, servesc in general pentru definirea unor
proprietati sau operatii comune ale mai multor clase si pentru a putea generaliza
operatiile referitoare la acestea. Putem, de exemplu sa definim in cadrul clasei
de obiecte om modul in care acesta se alimenteaza ca fiind independent de apartenenta
la conceptul de barbat sau femeie. Aceasta definitie va fi valabila la amandoua
subconceptele definite mai sus. In schimb, nu putem decat cel mult sa precizam
faptul ca un om trebuie sa aiba un comportament social. Descrierea exacta a
acestui comportament trebuie facuta in cadrul conceptului de barbat si a celui
de femeie. Oricum, este interesant faptul ca, indiferent care ar fi clasa acestuia,
putem sa ne bazam pe faptul ca acesta va avea definit un comportament social,
specific clasei lui.
Cele doua metode despre care am vorbit mai sus, definite la nivelul unui superconcept,
sunt profund diferite din punctul de vedere al subconceptelor acestuia. In timp
ce metoda de alimentatie este definita exact si amandoua subconceptele pot sa
o foloseasca fara probleme, metoda de comportament social este doar o metoda
abstracta, care trebuie sa existe, dar despre care nu se stie exact cum trebuie
definita.
Fiecare dintre subconcepte trebuie sa-si defineasca propriul sau comportament
social pentru a putea deveni instantiabil. Daca o clasa de obiecte are cel putin
o metoda abstracta, ea devine in intregime o clasa abstracta si nu poate
fi instantiata, adica nu putem crea instante ale unei clase de obiecte abstracte.
Altfel spus, o clasa abstracta de obiecte este o clasa pentru care nu
s-au precizat suficient de clar toate metodele astfel incat sa poata fi folosita
in mod direct. /sus.gif)
3.4 Derivarea claselor de obiecte
O alta proprietate interesanta a claselor de obiecte este aceea de ierarhizare.
Practic, ori de cate ori definim o noua clasa de obiecte care sa reprezinte
un anumit concept, specificam clasa de obiecte care reprezinta conceptul original
din care provine noul concept impreuna cu diferentele pe care le aduce noul
concept derivat fata de cel original. Aceasta operatie de definire a unei noi
clase de obiecte pe baza uneia deja existente o vom numi derivare. Conceptul
mai general se va numi superconcept iar conceptul derivat din acesta
se va numi subconcept. In acelasi mod, clasa originala se va numi superclasa
a noii clase in timp ce noua clasa de obiecte se va numi subclasa a clasei
derivate.
Uneori, in loc de derivare se foloseste termenul de extindere. Termenul vine
de la faptul ca o subclasa isi extinde superclasa cu noi variabile si metode.
In spiritul acestei ierarhizari, putem presupune ca toate clasele de obiecte
sunt derivate dintr-o clasa initiala, sa-i spunem clasa de obiecte generice,
in care putem defini proprietatile si operatiile comune tuturor obiectelor precum
ar fi testul de egalitate dintre doua instante, duplicarea instantelor sau aflarea
clasei de care apartine o anumita instanta.
Ierarhizarea se poate extinde pe mai multe nivele, sub forma arborescenta,
in fiecare punct nodal al structurii arborescente rezultate aflandu-se clase
de obiecte. Desigur, clasele de obiecte de pe orice nivel pot avea instante
proprii, cu conditia sa nu fie clase abstracte, imposibil de instantiat.
/cap3_02.gif)
Figura 3.2 O ierarhie de clase de obiecte in care clasele sunt
reprezentate in campuri eliptice iar instantele acestora in campuri dreptunghiulare.
Clasele abstracte de obiecte au elipsa dublata.
Desigur, este foarte dificil sa construim o ierarhie de clase de obiecte completa,
care sa contina clase de obiecte corespunzatoare fiecarui concept cunoscut.
Din fericire, pentru o problema data, conceptele implicate in rezolvarea ei
sunt relativ putine si pot fi usor izolate, simplificate si definite. Restrangerea
la minimum a arborelui de concepte necesar rezolvarii unei anumite probleme
fara a se afecta generalitatea solutiei este un talent pe care fiecare programator
trebuie sa si-l descopere si sa si-l cultive cu atentie. De alegerea acestor
concepte depinde eficienta si flexibilitatea aplicatiei.
O clasa de obiecte derivata dintr-o alta clasa pastreaza toate proprietatile
si operatiile acesteia din urma aducand in plus proprietati si operatii noi.
De exemplu, daca la nivelul clasei de obiecte om am definit forma bipeda a acestuia
si capacitatea de a vorbi si de a intelege, toate acestea vor fi mostenite si
de catre clasele derivate din clasa om, si anume clasa barbatilor si cea a femeilor.
Fiecare dintre aceste clase de obiecte derivate isi vor defini propriile lor
proprietati si operatii pentru a descrie diferenta dintre ele si clasa originala.
Unele dintre proprietatile si operatiile definite in superclasa pot fi redefinite
in subclasele de obiecte derivate. Vechile proprietati si operatii sunt disponibile
in continuare, doar ca pentru a le putea accesa va trebui sa fie specificata
explicit superclasa care detine copia redefinita. Operatia de redefinire a unor
operatii sau variabile din interiorul unei clase in timpul procesului de derivare
o vom numi rescriere.
Aceasta redefinire ne da de fapt o mare flexibilitate in constructia ierarhiei
unei probleme date pentru ca nici o proprietate sau operatie definita intr-un
punct al ierarhiei nu este impusa definitiv pentru conceptele derivate din acest
punct direct sau nu.
Revenind pentru un moment la protejarea informatiilor interne ale unui obiect
sa precizam faptul ca gradul de similitudine de care vorbeam mai sus este marit
in cazul in care vorbim de doua clase derivate una din cealalta. Cu alte cuvinte,
o subclasa a unei clase are acces de obicei la mult mai multe informatii memorate
in superclasa sa decat o alta clasa de obiecte oarecare. Acest lucru este firesc
tinand cont de faptul ca, uneori, o subclasa este nevoita sa redefineasca o
parte din functionalitatea superclasei sale. /sus.gif)
3.5 Interfete spre obiecte
Un obiect este o entitate complexa pe care o putem privi din diverse puncte
de vedere. Omul de exemplu poate fi privit ca un mamifer care naste pui vii
sau poate fi privit ca o fiinta ganditoare care invata sa programeze calculatoare
sau poate fi privit ca un simplu obiect spatio-temporal care are propria lui
forma si pozitie in functie de timp.
Aceasta observatie ne spune ca trebuie sa dam definitii despre ce inseamna
cu adevarat faptul ca un obiect poate fi privit ca un mamifer sau ca o fiinta
ganditoare sau ca un obiect spatio-temporal. Aceste definitii, pe care le vom
numi in continuare interfete, sunt aplicabile nu numai clasei de obiecte
om dar si la alte clase de obiecte derivate sau nu din acesta, superclase sau
nu ale acesteia. Putem sa gasim o multime de clase de obiecte ale caror instante
pot fi privite ca obiecte spatio-temporale dar care sa nu aiba mare lucru in
comun cu omul. Practic, atunci cand construim o interfata, definim un set minim
de operatii care trebuie sa apartina obiectelor care respecta aceasta interfata.
Orice clasa de obiecte care declara ca respecta aceasta interfata va trebui
sa defineasca toate operatiile.
Operatiile insa, sunt definite pe cai specifice fiecarei clase de obiecte in
parte. De exemplu, orice obiect spatial trebuie sa defineasca o operatie de
modificare a pozitiei in care se afla. Dar aceasta operatie este diferita la
un om, care poate sa-si schimbe singur pozitia, fata de o minge care trebuie
ajutata din exterior pentru a putea fi mutata. Totusi, daca stim cu siguranta
ca un obiect este o instanta a unui clase de obiecte care respecta interfata
spatio-temporala, putem linistiti sa executam asupra acestuia o operatie de
schimbare a pozitiei, fara sa trebuiasca sa cunoastem amanunte despre modul
in care va fi executata aceasta operatie. Tot ceea ce trebuie sa stim este faptul
ca operatia este definita pentru obiectul respectiv.
In concluzie, o interfata este un set de operatii care trebuiesc definite de
o clasa de obiecte pentru a se inscrie intr-o anumita categorie. Vom spune despre
o clasa care defineste toate operatiile unei interfete ca implementeaza interfata
respectiva.
Cu alte cuvinte, putem privi interfetele ca pe niste reguli de comportament
impuse claselor de obiecte. In clipa in care o clasa implementeaza o anumita
interfata, obiectele din clasa respectiva pot fi privite in exclusivitate din
acest punct de vedere. Interfetele pot fi privite ca niste filtre prin care
putem privi un anumit obiect, filtre care nu lasa la vedere decat proprietatile
specifice interfetei, chiar daca obiectul in vizor este mult mai complicat in
realitate.
Interfetele creaza o alta impartire a obiectelor cu care lucram. In afara de
impartirea normala pe clase, putem sa impartim obiectele si dupa interfetele
pe care le implementeaza. Si, la fel cu situatia in care definim o operatie
doar pentru obiectele unei anumite clase, putem defini si operatii care lucreaza
doar cu obiecte care implementeaza o anumita interfata, indiferent de clasa
din care acestea fac parte.