v9h11hg
3.1 Obiecte
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.
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.
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.
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.
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.
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.
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.