+ All Categories
Home > Documents > Prog calc

Prog calc

Date post: 12-Nov-2015
Category:
Upload: corinaionescu
View: 214 times
Download: 2 times
Share this document with a friend
Description:
Programare calculator
34
Programarea orientată obiect (Object Oriented Programming - OOP) reprezintă o tehnică ce s-a impus în ultimii ani, dovedindu-se benefică pentru realizarea sistemelor software de mare complexitate. Noţiunea de obiect datează din anii ’60, o dată cu apariţia limbajului Simula. Există limbaje - ca Smalltalk şi Eiffel - care corespund natural cerinţelor programării orientate obiect, fiind concepute în acest spirit, alături de care o serie de alte limbaje procedurale, printre care C++ şi Turbo Pascal, au fost dezvoltate astfel încât să ofere suport pentru această tehnică. În prezent există în funcţiune sisteme software de mare anvergură realizate în tehnica programării orientată obiect, principiile ei fiind suficient de bine clarificate, astfel încât să se treacă din domeniul cercetării în cel al producţiei curente de programe. 10.1 Modelul de date orientat pe obiecte OOP reprezintă o abordare cu totul diferită faţă de programarea funcţională, devenită deja “clasică”. Dacă în programarea clasică programatorul era preocupat să răspundă la întrebarea “ce trebuie făcut cu datele?”, adică să definească proceduri care să transforme datele în rezultate, în OOP accentul cade asupra datelor şi legăturilor care există între acestea, ca elemente prin care se modelează obiectele lumii reale. Se poate afirma, într-o primă analiză, că OOP organizează un program ca o colecţie de obiecte, modelate prin date şi legături specifice, care interacţionează dinamic, adică manifestă un anumit “comportament”, producând rezultatul scontat. În general, pentru modelul de date orientat pe obiect, se consideră definitorii următoarele concepte: obiect, încapsulare, moştenire şi polimorfism. 1. Obiectul este modelul informaţional al unei entităţi reale, care posedă, la un anumit nivel, o mulţime de proprietăţi şi care are, în timp, un anumit comportament, adică manifestă o reacţie specifică în relaţiile sale cu alte obiecte din mediul său de existenţă. Ca model, un obiect este o unitate individualizabilă prin nume, care conţine o mulţime de date, proceduri şi funcţii. Datele descriu OBIECTE ÎN PASCAL
Transcript
  • Programarea orientat obiect (Object Oriented Programming - OOP) reprezint o tehnic ce s-a impus n ultimii ani, dovedindu-se benefic pentru realizarea sistemelor software de mare complexitate. Noiunea de obiect dateaz din anii 60, o dat cu apariia limbajului Simula. Exist limbaje - ca Smalltalk i Eiffel - care corespund natural cerinelor programrii orientate obiect, fiind concepute n acest spirit, alturi de care o serie de alte limbaje procedurale, printre care C++ i Turbo Pascal, au fost dezvoltate astfel nct s ofere suport pentru aceast tehnic. n prezent exist n funciune sisteme software de mare anvergur realizate n tehnica programrii orientat obiect, principiile ei fiind suficient de bine clarificate, astfel nct s se treac din domeniul cercetrii n cel al produciei curente de programe.

    10.1 Modelul de date orientat pe obiecte

    OOP reprezint o abordare cu totul diferit fa de programarea funcional, devenit deja clasic. Dac n programarea clasic programatorul era preocupat s rspund la ntrebarea ce trebuie fcut cu datele?, adic s defineasc proceduri care s transforme datele n rezultate, n OOP accentul cade asupra datelor i legturilor care exist ntre acestea, ca elemente prin care se modeleaz obiectele lumii reale. Se poate afirma, ntr-o prim analiz, c OOP organizeaz un program ca o colecie de obiecte, modelate prin date i legturi specifice, care interacioneaz dinamic, adic manifest un anumit comportament, producnd rezultatul scontat. n general, pentru modelul de date orientat pe obiect, se consider definitorii urmtoarele concepte: obiect, ncapsulare, motenire i polimorfism.

    1. Obiectul este modelul informaional al unei entiti reale, care posed, la un anumit nivel, o mulime de proprieti i care are, n timp, un anumit comportament, adic manifest o reacie specific n relaiile sale cu alte obiecte din mediul su de existen. Ca model, un obiect este o unitate individualizabil prin nume, care conine o mulime de date, proceduri i funcii. Datele descriu

    OBIECTE N PASCAL

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    proprietile i nivelul acestora, iar funciile i procedurile definesc comportamentul. Avnd n vedere proprietile comune i comportamentul similar ale entitilor pe care le modeleaz, obiectele pot fi clasificate, adic mprite n mulimi. O mulime de obiecte de acelai fel constituie o clas, care poate fi descris prin modelul comun al obiectelor sale. De exemplu, n figura 10.1, numerele raionale, ca perechi de numere ntregi de forma (Numarator, Numitor) pot fi descrise printr-un model comun, denumit ClasaRational. Modelul arat c orice obiect de acest fel se caracterizeaz printr-o pereche de numere ntregi i c pe aceast mulime sunt definite operaii unare i binare, care arat cum interacioneaz obiectele n interiorul mulimii: un numr raional poate da natere opusului i inversului su, dou numere raionale pot produce un alt numr raional ca sum, diferen etc.

    ClasaRational

    Numarator: Integer Numitor: Integer

    Obiecte

    AddRational (b,c) SubRational (b,c) MulRational (b,c) DivRational (b,c) OpusRational (aopus) InversRational (ainvers)

    a: (5;7) b: (3;1) c: (2;5) d: (7;5) x: (0;1)

    Fig. 10.1 Clas i obiecte mulimea numerelor raionale

    Numerele complexe (figura 10.2), descrise ca perechi de numere reale de

    forma (p_real, p_imaginar) pot fi grupate ntr-un model comun, denumit Ccomplexe:

    CComplexe p_reala:real;

    p_imaginara:real; Conjugat(b) Suma(b,c)

    Inmultire(b,c) Modul:real;

    Diferenta(b,c) Impartire(b,c)

    Exemplu de obiect a:(2, 7.5) a reprezint numrul complex 2+7.5i

    Fig. 10.2 Clas i obiecte mulimea numerelor complexe

  • Obiecte n Pascal

    Generaliznd, se poate afirma c o clas de obiecte se manifest ca un tip obiect, iar modelul comun al obiectelor este modelul de definire a tipului obiect. Astfel, obiectele individuale apar ca manifestri, realizri sau instanieri ale clasei, adic exemplare particulare generate dup modelul dat de tipul obiect. Altfel spus, o clas poate fi considerat ca un tip special de dat, iar obiectele sale ca date de acest tip.

    Acceptarea acestei semnificaii pentru clase de obiecte este de natur s simplifice descrierea obiectelor i s asigure un tratament al acestora similar tipurilor structurate de date din limbajele de programare: este suficient o descriere a tipului obiect i apoi se pot declara constante i variabile de acest tip. Datele care reprezint proprietile obiectelor se numesc atribute i sunt de un anumit tip, de exemplu, ntregi, real, boolean etc. Procedurile i funciile care definesc comportamentul obiectelor sunt cunoscute ca metode ale clasei. mpreun, atributele i metodele sunt membrii clasei, identificabili prin nume. Pentru a pune n eviden faptul c un membru aparine unui obiect se utilizeaz calificarea (notaia cu punct): nume_obiect.nume_membru. n figura 10.1, a.Numarator refer valoarea 5, iar a.AddRational(b,x) refer metoda AddRational a obiectului a pentru a produce obiectul rezultat x= a+b. Aa cum sugereaz figura 10.1, obiectele trebuie s conin valorile lor pentru atribute, deoarece definesc starea obiectului respectiv. Metodele, fiind comune, se specific o singur dat. Despre o metod, desemnat sau apelat cu un anumit obiect, se spune c se execut n context obiect, iar obiectul respectiv este numit curent. Apelul propriu-zis este considerat ca trimitere de mesaj la obiectul curent, iar execuia metodei reprezint rspunsul obiectului curent la mesaj. Faptul c o metod se execut n contextul obiectului curent nseamn c are, n mod implicit, acces la atributele i metodele obiectului, altele dect metoda respectiv. Pentru alte obiecte, din aceeai clas sau din clase diferite, metoda trebuie s posede parametrii corespunztori. De asemenea, pentru a simplifica scrierea, n interiorul unei metode referirea la membrii obiectului curent se face fr calificare. Pe baza acestor convenii, n procedurile AddRational i OpusRational, scrise n pseudocod, s-a specificat cu un parametru mai puin dect numrul de operanzi pe care i presupune operaia respectiv, deoarece un operand este obiectul curent. Referirea la obiectul curent se distinge de celelalte prin lipsa calificrii.

    Procedure AddRational (b,c); c.Numrtor:= Numarator * b.Numitor + Numitor * b. Numarator; c.Numitor: = Numitor * b.Numitor; End;

    Procedure OpusRational (aopus); aopus.Numarator: = -Numarator; aopus.Numitor: = Numitor; End;

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Descrierea n pseudocod a metodelor Conjugat, Suma i Modul din clasa Ccomplexe (figura 10.2) poate fi fcut astfel:

    procedure Conjugat(b); begin

    b.p_reala:=p_reala; b.p_imaginara:=-p_imaginara;

    end; procedure Suma(b,c);

    begin c.p_reala:=p_reala+b.p_reala; c.p_imaginara:=-p_imaginara+b.p_imaginara;

    end; function Modul:real; begin Modul:=sqrt(sqr(p_reala)+sqr(p_imaginra)); end;

    Deoarece o clas este un tip de dat, n definirea unei clase B se pot declara atribute de tip A, unde A este la rndul ei o clas. Mai mult, o clas A poate defini atribute de tip A. De exemplu, clasa Carte din figura 10.3 are atributul Autor de tipul Persoana care este, de asemenea, o clas. Mai mult, Persoana are atributul Sef, care este de acelai tip (Persoana).

    Persoana 1 100 Persoana Carte Ionescu Scriitor Persoana 2

    Marca: Integer Nume: String Profesia: String Sef: Persoana

    Cota: String Titlu: String Autor:Persoana Pret: Real

    Persoana 2

    70 Popescu Reporter ----------

    Fig. 10.3 Atribute de tip

    Definirea atributelor unei clase ca tipuri ale altei clase pune n eviden o relaie ntre clase i, deci, ntre obiectele acestora. Din punct de vedere funcional, metodele unei clase au destinaii diverse. n multe cazuri i depinznd de limbaj, unei clase i se poate defini o metod constructor i o metod destructor. Un constructor este o metod care creeaz un

  • Obiecte n Pascal

    obiect, n sensul c i aloc spaiu i/sau iniializeaz atributele acestuia. Destructorul este o metod care ncheie ciclul de via al unui obiect, elibernd spaiul pe care acesta l-a ocupat. 2. ncapsularea exprim proprietatea de opacitate a obiectelor cu privire la structura lor intern i la modul de implementare a metodelor. Ea este legat de securitatea programrii, furniznd un mecanism care asigur accesul controlat la starea i funcionalitatea obiectelor. Se evit astfel modificri ale atributelor obiectelor i transformri ale acestora care pot s le deterioreze. Potrivit acestui mecanism, o clas trebuie s aib membrii mprii n dou seciuni: partea public i partea privat. Partea public este constituit din membri (atribute i metode) pe care obiectele le ofer spre utilizare altor obiecte. Ea este interfaa obiectelor clasei respective cu lumea exterioar i depinde de proiectantul clasei. Modalitatea extrem de constituire a interfeei este aceea a unei interfee compus numai din metode. Dac se dorete ca utilizatorii obiectelor clasei s poat prelua i/sau stabili valorile unor atribute ale acestora, interfaa trebuie s prevad metode speciale, numite accesorii. Partea privat cuprinde membri (atribute i/sau metode) care servesc exclusiv obiectelor clasei respective. De regul, n aceast parte se includ atribute i metode care faciliteaz implementarea interfeei. De exemplu, o stiv, ca tip de dat, poate fi descris de o clas stack n care interfaa este constituit din metodele Push, Pop, Top, Empty, n timp ce pointerul la capul stivei, Cap i numrtorul de noduri, Contor, ca atribute, sunt ascunse n partea privat. Ea se servete de obiectele altei clase, denumit Nod, ale crei obiecte le nlnuiete n stiv (figura 10.4). Trebuie remarcat c ncapsularea nseamn i faptul c utilizatorul metodelor nu trebuie s cunoasc codul metodelor i nici nu trebuie s fie dependent de eventuala schimbare a acestuia, interfaa fiind aceea care i ofer funcionalitate obiectelor n condiii neschimbate de apelare.

    Stack Cap: Nod Contor: Integer

    Partea privat

    Push ( ) Pop ( ) Top ( ) Empty ( )

    Interfaa(partea public)

    Fig. 10.4 Interfaa obiectelor

    3. Motenirea reprezint o relaie ntre clase i este, probabil, elementul definitoriu al OOP. Relaia permite constituirea unei noi clase, numit derivat, pornind de la clase existente, denumite de baz. Dac n procesul de construire particip o singur clas de baz, motenirea este simpl, altfel este multipl. n

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    continuare se vor aborda cteva aspecte legate de motenirea simpl, singura implementat n Pascal. Se spune c o clas D motenete o clas A, dac obiectele din clasa D conin toate atributele clasei A i au acces la toate metodele acestei clase. Din aceast definiie, dac D motenete A, atunci obiectele din D vor avea toate atributele i acces la toate metodele lui A, dar n plus:

    - D poate defini noi atribute i metode; - D poate redefini metode ale clasei de baz; - metodele noi i cele redefinite au acces la toate atributele dobndite sau

    definite. n figura 10.5, clasa Cerc motenete clasa Point, deci un obiect de tipul Cerc va avea ca membri coordonatele x,y motenite i ca atribut propriu Raza. Funcia Distana, definit pentru calculul distanei dintre punctul curent i punctul p, dat ca parametru, este accesibil i pentru obiectele Cerc i va calcula distana dintre dou cercuri (distana dintre centrele lor). Funcia Arie i procedura Deseneaz sunt redeclarate de clasa Cerc, ceea ce nseamn redefinirea lor impus de codul diferit pe care trebuie s-l aib n funcie de tipul figurilor geometrice (cerc sau alt figur).

    Point x: Integer y: Integer Deseneaz ( ) Distana (p:Point): Real

    x: 30 y: 150

    Cerc Raza: Integer Arie ( ): Real Deseneaz ( )

    x: 200 y: 180 Raza: 50

    Fig. 10.5 Motenirea simpl

    Dac se au n vedere mulimi de clase, atunci se observ c relaia de motenire simpl induce un arbore ierarhic de motenire pe aceast mulime. Exist o singur clas iniial, i anume rdcina arborelui, fiecare clas are un singur ascendent (printe) i orice clas care nu este frunz poate avea unul sau mai muli descendeni (fii). n fine, cu privire la motenirea simpl se pot face urmtoarele observaii: dac se aduc modificri n clasa de baz, prin adugarea de atribute i/sau metode, nu este necesar s se modifice i clasa derivat; motenirea permite specializarea i mbogirea claselor, ceea ce nseamn c, prin redefinire i adugare de noi membri, clasa derivat are, n parte, funcionalitatea clasei de baz,

  • Obiecte n Pascal

    la care se adaug elemente funcionale noi; motenirea este mecanismul prin care se asigur reutilizarea codului, sporind productivitatea muncii de programare. 4. Polimorfismul este un concept mai vechi al programrii, cu diferite implementri n limbajele de programare care se bazeaz pe tipuri de date (limbaje cu tip). Ea i-a gsit extensia natural i n modelul orientat pe date, implementat prin limbaje cu tip, n care clasa reprezint tipul de date obiect. Polimorfismul n limbajele de programare cu tip. Noiunea de polimorfism exprim capacitatea unui limbaj de programare cu tip de a exprima comportamentul unei proceduri independent de natura (tipul) parametrilor si. De exemplu, o procedur care determin cea mai mare valoare dintr-un ir de valori este polimorfic dac poate fi scris independent de tipul acestor valori. n funcie de modul de implementare, se disting mai multe tipuri de polimorfism.

    Polimorfismul ad-hoc se materializeaz sub forma unor proceduri care au toate acelai nume, dar se disting prin numrul i/sau tipul parametrilor. Polimorfismul este denumit i suprancrcare, avnd n vedere semantica specific fiecrei proceduri n parte.

    Polimorfismul de incluziune se bazeaz pe o relaie de ordine parial ntre tipurile de date, denumit relaie de incluziune sau inferioritate. Dac un tip A este inclus (inferior) ntr-un tip B, atunci se poate pasa un parametru de tip A la o procedur care ateapt un parametru de tip B. Astfel, o singur procedur definete funcional o familie de proceduri pentru toate tipurile inferioare celor declarate ca parametri. Un exemplu clasic este cazul tipului ntreg, inferior tipului real n toate operaiile de calcul.

    Polimorfismul parametric const n definirea unui model de procedur pentru care nsei tipurile sunt parametri. Polimorfismul, denumit i genericitate, presupune c procedura se genereaz pentru fiecare tip transmis la apel ca parametru. Cele trei tipuri de polimorfism exist (toate sau numai o parte din ele) n limbajele clasice de programare, dar unele pot s nu fie accesibile programatorului. Aa este cazul limbajului Pascal n care polimorfismul ad-hoc este implicit numai pentru operatorii limbajului (+, -, /, * etc), polimorfismul parametric nu este implementat, iar polimorfismul de incluziune este aplicabil numai funciilor i procedurilor de sistem. Polimorfismul n limbajele orientate obiect. Limbajele orientate obiect sau extensiile obiect ale unor limbaje cu tip ofer, n mod natural, polimorfismul ad-hoc i de incluziune. Polimorfismul ad-hoc intrinsec reprezint posibilitatea de a defini n dou clase independente metode cu acelai nume, cu parametri identici sau diferii. Acest polimorfism nu necesit mecanisme speciale i decurge simplu, din faptul c fiecare obiect este responsabil de tratarea mesajelor pe care le primete. Polimorfismul este de aceeai natur i n cazul n care ntre clase exist o relaie de motenire, cu precizarea c, n cazul n care o metod din clasa derivat are parametrii identici cu ai metodei cu acelai nume din clasa de baz, nu mai este

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    suprancrcare, ci redefinire, dup cum s-a precizat n paragraful anterior. Polimorfismul de incluziune este legat de relaia de motenire i de aceea se numete polimorfism de motenire. ntr-adevr, relaia de motenire este de ordine parial. Cnd clasa D motenete direct sau indirect clasa A, atunci D este inferior lui A. n aceste condiii, orice metod a lui A este aplicabil la obiectele de clas D i orice metod, indiferent de context, care are definit un parametru de tip A (printe) poate primi ca argument corespunztor (parametru actual) un obiect de clas D (fiu). Observaie: un obiect de clas A nu poate lua locul unui obiect de clas D, deoarece A acoper numai parial pe D, care este o extensie i o specializare a lui A. Limbajul Turbo Pascal, ca suport pentru programarea obiect, ofer ambele forme de polimorfism pentru clase. Legarea static i dinamic a metodelor. Legarea static a metodelor se regsete att n limbajele orientate obiect ct i n cele clasice. Compilatorul poate determina care metod i din care clas este efectiv apelat ntr-un anumit context i poate genera codul de apel corespunztor. n plus, datorit polimorfismului i lucrului cu pointeri, n limbajele orientate obiect, unui obiect din clasa printe, desemnat indirect prin referin (pointer) i nu prin nume, i se poate atribui un obiect fiu. n general, nu este posibil de determinat dac, n contextul dat, metoda polimorfic trebuie apelat n varianta clasei de baz sau a celei derivate. De aceea, compilatorul genereaz un cod care, la momentul execuiei, va testa tipul efectiv al obiectului i va realiza legarea metodei adecvate. n acest caz legarea este dinamic (sau la momentul execuiei). Legarea dinamic este mai costisitoare dect cea static, dar reprezint o necesitate pentru a asigura elasticitatea necesar n realizarea programelor OOP, obiectele putnd avea caracter de variabile dinamice.

    10.2 Clase i obiecte n Pascal Turbo Pascal implementeaz tehnica OOP pe fondul caracteristicilor sale de limbaj procedural, ceea ce nseamn c lucrul cu clase i obiecte se realizeaz asemntor cu cel cu tipuri structurate de date, mecanismul de ncapsulare fiind asigurat prin construirea unitilor.

    10.2.1 Specificarea claselor n Pascal, clasele sunt tratate asemntor datelor de tip articol. innd seama de faptul c o clas conine att date ct i metode, specificarea unei clase presupune declararea structurii i definirea metodelor.

  • Obiecte n Pascal

    Declararea structurii. Declararea unei clase, ca tip, se face n seciunea TYPE sub urmtoarea form general: referinta_la_clasa = ^nume_clasa {optional} nume_clasa=OBJECT atribut_1; ............... atribut_n; metoda_1; ............... metoda_m; { PRIVATE atribut_1; ............... atribut_p; metoda_1; ............... metoda_q; } END;

    Fiecare declaraie de atribut are forma: nume_atribut:tip, unde tip poate fi predefinit sau definit anterior de utilizator, inclusiv numele unui alt tip de clas. La fel ca i la tipul RECORD, unele atribute pot fi referine, chiar la tipul clasei care se definete, caz n care declararea tipului referin aferent trebuie s precead declararea clasei. O declaraie de metod cuprinde numai antetul unei funcii sau proceduri (signatura), adic numele, parametrii formali (dac exist) i tipul rezultatului, dac este cazul. Apariia opional a seciunii PRIVATE n declaraia de clas anun partea privat a clasei. Toate atributele i metodele care preced aceast seciune sunt considerate publice. n fine, se remarc prezena cuvntului OBJECT ca declarator de tip obiect. n Turbo Pascal nu exist un declarator CLASS, pentru a introduce o clas, aa cum exist, de exemplu, n C++. Deci declaratorul, OBJECT, nu declar un obiect, ci o clas de obiecte. Definirea. Definirea metodelor const n construirea corpurilor subprogramelor a cror signatur a fost precizat. Deoarece ntr-un program pot s existe mai multe clase, definirea trebuie s asigure recunoaterea metodelor diferitelor clase. Acest lucru se realizeaz prin prefixarea numelui metodei cu numele clasei. n rest, corpul metodelor se scrie n conformitate cu regulile generale ale limbajului i avnd n vedere c metoda respectiv se execut n contextul obiectului curent.

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Exemplu: 10.1. Declararea i definirea unei clase { Declararea clasei Point}

    Point = OBJECT Function Getx:Integer; Function Gety:Integer; Procedure Init (a, b: Integer); Function Distance (p: Point): Real; Private x: Integer; y: Integer; END; { Definirea metodelor} Function Point.Getx: Integer; Begin Getx: = x; End; Function Point.Gety: Integer; Begin Gety: = y; End: Function Point.Distance (p:Point): Real; Var dx, dy: Integer; Begin dx: = x-p.x; dy: = y-p.y; Distance: = sqrt(dx*dx-dy*dy); End; Procedure Point.Init(a, b: Integer); Begin x: = a; y: = b; End; Din exemplul, 10.1 se observ modul de declarare a unei clase, n care, pentru asigurarea ncapsulrii depline, comunicarea cu exteriorul se face numai prin interfa. Funciile Getx i Gety sunt necesare ca accesorii pentru a returna valorile atributelor x i y, iar procedura Init este un constructor care iniializeaz (schimb) valorile celor dou atribute. Funcia Distance ilustreaz modul n care trebuie neleas afirmaia c o metod se execut n context obiect. Se observ c, dei calculul distanei presupune dou obiecte de tip Point, ca parametru figureaz numai un punct, p. Unde este cellalt (primul)? n mod implicit, se consider c primul punct este un obiect ascuns, obiectul de apel al funciei, numit curent, coordonatele sale fiind x i y. n relaiile de calcul, referirea coordonatelor celuilalt punct, transmis ca argument, se va face prin notaia cu calificri: p.x, p.y. Rezult de aici c funciile Getx, Gety i procedura Init se refer la obiectul curent.

  • Obiecte n Pascal

    Unit de clas. Deoarece clasele trebuie s fie prin definiie entiti reutilizabile, se ncapsuleaz ntr-o unitate. Declararea claselor apare n seciunea INTERFACE, iar definirea metodelor n seciunea IMPLEMENTATION. Se recomand ca fiecare clas s fie o unitate.

    10.2.2 Utilizarea obiectelor

    Obiectele unei clase se comport asemntor variabilelor de tip articol. Sintetiznd aceasta, nseamn c:

    Obiectele se declar, ca i variabilele, ntr-o seciune VAR dintr-o entitate de program (program principal, funcie, procedur sau unitate). De aici rezult c obiectele pot avea caracter global sau local, ceea ce determin, pe de o parte, spaiul de vizibilitate, iar, pe de alt parte, durata de via i segmentul de alocare.

    Un obiect poate fi declarat static sau dinamic. Atributul de static, respectiv dinamic, se refer la momentul n care are loc alocarea spaiului pentru obiect (la compilare sau la execuie).

    Deoarece declararea obiectelor dinamice va fi tratat ntr-un alt paragraf, n continuare se prezint numai aspectele privind obiectele statice. Pentru obiectele statice declaraia are forma: nume_obiect:nume_clasa. De exemplu: p1, p2 : Point. Ca i n cazul variabilelor, obiectele declarate trebuie s fie iniializate nainte de a fi utilizate. Se apeleaz, n acest sens, o metod de tip constructor. De exemplu, p2.Init (30,100) iniializeaz punctul p2 cu x = 30 i y = 100.

    Dou obiecte de acelai tip pot participa ntr-o operaie de atribuire. De exemplu, p1: = p2. Atribuirea ntre obiecte nu este ntotdeauna corect. Dac obiectele au spaiu extins, atunci copierea nu este corect. De aceea, atribuirile trebuie utilizate cu mult atenie, ele realizndu-se prin copiere bit cu bit.

    Un obiect poate participa ca argument, prin valoare sau referin, la apelul de procedur sau funcie. Deoarece transferul prin valoare corespunde unei copieri, pot aprea aceleai neajunsuri ca i la operaia de atribuire. n plus, copierea poate fi i costisitoare ca spaiu i timp. De aceea se prefer transferul prin referin. O funcie nu poate returna ca rezultat un obiect, dar poate returna o referin la un obiect.

    Orice metod a unei clase, inclusiv constructorii, se apeleaz cu un anumit obiect care devine acti sau curent . Apelul are forma:

    obiect.nume_metoda(alte_argumente). De exemplu: pr. Init( 70,80); d:= p1.Distance (p2). Obiectul de apel este un parametru ascuns care se asociaz automat cu un parametru formal denumit Self. Acest parametru formal prefixeaz, n mod

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    implicit, atributele i metodele utilizate de metoda apelat. Se poate spune c Self este un pseudonim al obiectului de apel i, de aceea, n metoda apelat se poate scrie: Self.atribut sau Self.metoda. Uneori Self se utilizeaz explicit pentru a evita ambiguitatea referirii sau atunci cnd este nevoie de a obine adresa unui obiect curent. n ultimul caz, adresa se desemneaz prin @Self. Exemplu:

    10.2. Se declar i se definete o clas de numere raionale ca perechi (Numarator, Numitor) de numere ntregi. O astfel de clas poate fi util n calcule cu fracii ordinale, atunci cnd transformarea acestora n fracii zecimale (numere reale) nu este de dorit din cauza erorilor de trunchiere. UNIT ClasaRat; INTERFACE Type Rational = OBJECT Procedure InitRat (x, y:Integer); Procedure AddRat (b: Rational; VAR c: Rational); Procedure SubRat (b: Rational; VAR c: Rational); Procedure MulRat (b: Rational; VAR c: Rational); Procedure DivRat (b: Rational; VAR c: Rational); Procedure OpusRat (VAR c: Rational); Procedure InversRat (VAR c: Rational); Function GetNumarator: Integer; Function GetNumitor: Integer; Procedure ReadRat; Procedure WriteRat; Function CompRat (b: Rational): Integer; PRIVATE Numarator, Numitor: Integer; Procedure SignRat; END; IMPLEMENTATION

    Function Cmmdc (x,y: Integer ):integer:FORWARD; Procedure Rational. InitRat (x, y: Integer); {Initializeaza in forma inductiva functia (numarator, numitor)} Var d: Integer; Begin If (x=0) or (y=1) then y=1 else begin

    If (abs(x)1) and (abs(y)1) then begin

    d:= Cmmdc (x,y) x:= x/d; y:= y/d; end; SignRat; End; Numarator:= x; Numitor:= y; End;

    Procedure Rational.AddRat (b: Rational; VAR c: Rational); Var x, y: Integer; Begin

    x: = Numarator*b.Numarator+Numitor*b.Numarator;

  • Obiecte n Pascal

    y: = Numitor*b.Numitor; c.InitRat (x, y); End;

    Procedure Rational.SubRat (b:Rational; VAR c:Rational); Var

    r: Rational; Begin b. OpusRat ( r ); AddRat (r, c); End;

    Procedure Rational.MulRat (b: Rational; VAR c: Rational); Var x, y: Integer; Begin x: = Numarator*b.Numarator; y: = Numitor*b.Numitor; c.InitRat (x, y); End;

    Procedure Rational.DivRat (b: Rational; VAR c: Rational); Var r: Rational; Begin b.InversRat ( r ); MulRat (r, c); End;

    Procedure Rational.InversRat (VAR c: Rational); Var d: Integer; Begin d:= Numarator; if d=0 then d:=1; c.Numarator: = c.Numitor; c.Numitor: = d; c.SignRat; End;

    Procedure Rational.OpusRat (VAR c: Rational); Begin c.Numarator: = - c.Numarator; End;

    Function Rational.GetNumarator: Integer; Begin GetNumarator: = Numarator; End;

    Function Rational.GetNumitor: Integer; Begin GetNumitor: = Numitor; End;

    Procedure Rational.SignRat; Begin if (Numarator>0) and (Numitor

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Begin x: = abs (x); y: = abs (y); While x< >y Do if x>y then x: = x-y else y: = y-x; Cmmdc: = x; End;

    Procedure Rational.ReadRat; Var txt: String [ 25]; i, x, y: Integer; Begin Read (txt); i: Pos (txt, /); If (i=0) then Begin {Numarator ntreg} Val (txt, Numarator); Numitor: =1; End else Begin Val(Copy (txt, 1, C-1), x); Val (Copy (txt, i, 25), y); InitRat (x, y); End; End;

    Procedure Rational.WriteRat; Begin Write (Numarator, /, Numitor); End;

    Function Rational.CompRat (b: Rational): Integer; Var d, n1, n2: Integer; Begin d: = cmmdc (Numitor, b.Numitor); n1: = Numarator*(dDIVNumitor); n2: = b.Numarator*(dDIV b.Numitor); if (n1

  • Obiecte n Pascal

    WriteLn (M/m - Inmulire); WriteLn (D/d - Impartire); WriteLn (C/c - Comparare); WriteLn (G/g - Elemente); WriteLn (T/t - Terminare); WriteLn ( Alege operatia:); ReadLn ( Op ); Op: = UpCase ( Op ); End; BEGIN Meniu; While Op T Do Begin If (Op = G) then Begin a.ReadRat; WriteLn (Numarator=, a.GetNumarator); WriteLn (Numitor=, a.GetNumitor); End else If (Op = C) then Case a.CompRat (b) of -1: WriteLn ( ab); End else Begin CaseOp of A: a.AddRat (b,c); S: a.SubRat (b,c); M: a.MulRat (b,c); D: a.DivRat (b,c); End; C.WriteRat; End; Meniu; End; END. La fel ca n exemplul 10.1, i n acest caz atributele sunt private, iar accesul la valorile lor se asigur prin accesoriile GetNumarator, GetNumitor. n partea privat apare o metod care este utilizat numai intern (n clas), n scopul asocierii semnului numrului raional la numrtor. De asemenea, se remarc prezena funciei Cmmdc (cel mai mare divizor comun) care nu ine de clas, dar este necesar implementrii unor metode ale clasei. La stabilirea numrului de parametri, n conceperea metodelor s-a avut n vedere c un operand, eventual unicul pentru operaii unare, este obiectul curent. Atunci cnd, n contextul obiectului curent, s-a apelat o metod care se refer la un alt obiect, acesta este precizat explicit, (altfel s-ar considera acelai context). De exemplu, n operaiile de scdere i mprire se aplic o reducere la operaiile de adunare cu opusul, respectiv nmulire cu inversul. Acest rezultat intermediar se obine prin b.OpusRat(r), respectiv b.InversRat(r), dup care, n contextul definit la apelul lui SubRat, respectiv DivRat se invoc AddRat(r,c) i MulRat(r,c), ceea ce

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    nseamn c ele vor fi de fapt apelate ca Self.AddRat(r,c) i Self.MulRat(r,c), adic a va fi prim operand.

    O meniune aparte trebuie fcut cu privire la constructorul InitRat care iniializeaz n form ireductibil fracia (Numarator, Numitor) a unui obiect. De aceea, ea este apelat ori de cte ori se creeaz o astfel de fracie, fie n programul principal, fie ntr-o alt metod. Metodele ReadRat i WriteRat realizeaz legtura obiectelor cu tastatura i monitorul. Procedura ReadRat ofer o alternativ de iniializare a obiectelor, prin citirea fraciilor de la tastatur sub forma x/y sau x, dac numitorul este unu (numr ntreg). Procedura WriteRat afieaz pe monitor un numr raional sub form de fracie x/y, n poziia curent de scriere. n cazul claselor numerice (dar nu numai), pe mulimea obiectelor unei clase se poate defini o relaie de ordine. Deoarece limbajul nu permite suprancrcarea operatorilor, este necesar s se introduc o metod, de regul o funcie, care s defineasc relaia. Este cazul funciei CompRat care compar dou numere raionale a, b i returneaz -1, 0, 1, dup cum ntre cele dou numere exist una din relaiile: ab. Legat de precizrile referitoare la suprancrcarea operatorilor, se observ o lips de naturalee n scrierea operaiilor definite pe mulimea obiectelor. De exemplu, se scrie a.AddRat(b, c) n locul formei c:=a+b sau a.CompRat (b) n loc de a

  • Obiecte n Pascal

    Spaiu compact Spaiu extins (static) (dinamic)

    atribut _1 referinta _1 atribut _2 atribut _3 referinta _2

    Fig. 10.6 Spaiul extins al unui obiect

    Atunci cnd se declar o variabil obiect dintr-o astfel de clas, compilatorul poate aloca spaiul compact necesar. Spaiul extins, la acest moment, este necunoscut deoarece el trebuie s fie alocat n zona memoriei dinamice, la momentul execuiei. Rezult de aici dou aspecte importante pe care trebuie s le aib n vedere proiectantul clasei. n primul rnd, trebuie s se prevad un constructor capabil s trateze nu numai iniializarea atributelor statice, dar i a celor care ocup un spaiu dinamic. Constructorul trebuie s utilizeze procedura New sau GetMem pentru a obine un bloc de mrimea necesar, a crui adres trebuie ncrcat n cmpul referin al obiectului, iar blocul respectiv trebuie apoi iniializat.

    ntr-o clas pot fi prevzui mai muli constructori specializai, dac exist mai multe cmpuri de tip referin la un obiect, dac un singur constructor ar fi incomod de utilizat sau ar avea o list prea mare de parametri. Mai mult, limbajul prevede o posibilitate special de a declara un constructor, utiliznd declaratorul Constructor n loc de Procedure. Printr-o astfel de declarare, compilatorul are posibilitatea s disting din mulimea metodelor pe cele care au acest rol special, lucru necesar n cazul motenirii, dar util i programatorului pentru a putea verifica mai uor dac a rezolvat corect problema iniializrii obiectelor. n alt doilea rnd, atunci cnd un obiect trebuie s-i ncheie existena (de exemplu, la ieirea dintr-o funcie/procedur n care a fost creat), este necesar s se prevad o metod destructor care s elibereze spaiul extins. Destructorul trebuie s apeleze procedura Dispose sau FreeMem pentru a returna acest spaiu zonei heap. n lipsa unui destructor rmn blocuri de memorie ocupate, fr ca ele s mai poat fi referite ulterior. Declaraia destructorului se poate face prin declaratorul Destructor n loc de Procedure. Constructorii i destructorii pot avea orice utilitate pe care o consider programatorul, atunci cnd se creeaz sau se distrug obiecte.

    Atribuirea ntre obiectele care au spaiu extins are unele particulariti. Astfel, dac se specific atribuirea a:=b, atunci se realizeaz o copiere bit cu bit a obiectului b n a. Dup operaie, a i b au acelai coninut n spaiul compact i, deci, refer acelai spaiu extins (figura 10.7).

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    x y z

    .

    .

    .

    Referin

    xyz

    .

    .

    .

    Referin

    Fig. 10.7 Atribuirea n cazul obiectelor cu spaiu extins

    a:=b

    Spaiu extins

    Ulterior, modificarea realizat la unul din obiecte n spaiul extins

    afecteaz starea i pentru cellalt obiect. Dac un obiect dispare, atunci cellalt obiect va rmne fr spaiu extins, iar cnd i acesta va disprea, destructorul su va ncerca s elibereze un spaiu care nu mai exist, fiind deja eliberat. n legtur cu astfel de cazuri, deoarece operatorul de atribuire nu poate fi suprancrcat, este necesar s se evite operaia i s se prevad o metod proprie de copiere prin care s se iniializeze a cu valorile lui b, dar n spaiu complet separat. De asemenea, se recomand ca obiectele de acest fel, utilizate ca argumente, s fie transmise, prin referin i nu prin valoare, avnd n vedere c ultima metod este echivalent cu o atribuire.

    Exemplu:

    10.3. Se ilustreaz modul de utilizare a referinelor n declararea claselor, de realizare a constructorilor multipli i a destructorului de spaiu extins. Dei simplificat, exemplul sugereaz modul n care se poate construi o clas matrice cu elemente de tip Rational, prin utilizarea clasei din exemplul 10.2. UNIT ClasaMRat; INTERFACE

    uses ClasaRat; Const MaxLin = 10; MaxCol = MaxLin; ZeroRat : Rational = (Numarator:0; Numitor:1); Type DimLin = 1..MaxLin;

    DimCol = 1..MaxCol; Matrice = array [DimLin, DimCol] of Rational; MatriceRat = OBJECT Constructor SetNulMat (m, n:Integer); Constructor ReadMat; Procedure AddMat (b:MatriceRat; VAR c:MatriceRat); Procedure WriteMat; Destructor FreeExtMat; PRIVATE

  • Obiecte n Pascal

    Nlin, Ncol:Integer; PMat:^Matrice; END; Var ErrMat:Integer; IMPLEMENTATION Constructor MatriceRat.SetNulMat (m, n:Integer); Var i, j:Integer; Begin m:=Max (m, MaxLin); n:=Max (n, MaxCol); GetMem (Pmat, m*n*SizeOf (Rational)); For i:=1 to m Do For j:=1 to n Do P.Mat^[i, j]:=ZeroRat; Nlin:= m; Ncol:=n; End;

    Constructor MatriceRat.ReadMat; Var m, n, i, j:Integer; Begin Repeat Write (Numrul de linii:); ReadLn (m); Until m

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Begin WriteLn (Linia:, i); For j:=1 To Ncol Do Begin PMat^[i, j].WriteRat; If (iNcol) Write (;); End; End; End;

    Program Test; Uses ClasMat; Var A,B,C:MatriceRat; Begin A.ReadMat; B.ReadMat; A.AddMat (B,C); If(ErrMat)then WriteLn (** Eroare:Dimensiuni diferite) else C.WriteMat; A.FreeExtMat; B.FreeExtMat; C.FreeExtMat; ReadLn; END. Analiza exemplului pune n eviden posibilitile tehnicii OOP n limbajul Pascal. Iniializarea unor variabile de tip obiect, n seciunea CONST. Este cazul variabilei ZeroRat, pentru care se observ tratarea iniializrii ca n cazul articolelor, definindu-se variabile pentru fiecare atribut, potrivit tipului su. Definirea structurii de tip array, la care tipul de baz este un tip obiect. Tipul Rational permite definirea unui tip nou, Matrice, ca un masiv bidimensional. Alocarea dinamic a spaiului pentru matrice drept spaiu extins, potrivit numrului de linii i coloane, dar fr a se depi dimensiunile declarate ale tipului Matrice. Se elimin, astfel, risipa de spaiu prin alocarea static, la dimensiuni constante, pentru structura de tip masiv. De observat modul de referire a elementelor matricei i utilizarea metodelor clasei Rational pentru a trata aceste elemente. Se spune c ntre clasa MatriceRat i clasa Rational exist o relaie de tip client-server. Prezena mai multor constructori i a unui destructor pentru iniializarea, inclusiv a spaiului extins i, respectiv, eliberarea acestuia. Destructorul este apelat la sfritul programului, pentru fiecare obiect. Spaiul compact al obiectelor face obiectul eliberrii numai n cazul obiectelor locale, la ieirea din procedura sau funcia n care obiectele au fost create, cnd este automat returnat stivei. Tratarea erorilor clasei prin intermediul unei variabile publice (din interfa). Aceasta este utilizat n cazul operaiei de adunare i returneaz valoarea unu dac matricele nu au aceeai dimensiune, respectiv zero, n caz contrar. Este sarcina programului care apeleaz metodele clasei s verifice, la rentoarcerea

  • Obiecte n Pascal

    controlului, ce valoare are variabila public. Variabila nu este legat de clas, ci de unitatea n care este ncorporat clasa.

    10.2.4 Utilizarea obiectelor dinamice

    Obiectele statice nu sunt, n general, reprezentative pentru tehnica OOP. Cel mai frecvent, obiectele au un comportament dinamic, adic n timp se nasc, triesc i dispar. n mod corespunztor, trebuie s existe posibilitatea gestionrii dinamice a spaiului lor, astfel nct, cu aceleai rezerve de memorie, s poat fi utilizate obiecte multiple, eventual de tipuri diferite. n limbajele orientate obiect, obiectele sunt, prin definiie, dinamice i sistemul preia sarcina de a aloca i elibera spaiul de memorie pentru acestea.Tehnica OOP implementat n Pascal face uz de facilitile de definire a variabilelor dinamice, dar gestiunea obiectelor este lsat exclusiv n sarcina programatorului. n aceste condiii, declararea obiectelor dinamice se poate face n una din formele: nume_referinta_clasa : ^nume_clasa; nume_referinta_clasa : nume_tip_referinta; Prima form corespunde declarrii cu tip anonim a variabilelor i este mai puin indicat. A doua form utilizeaz explicit un tip referin spre clas i este posibil numai dac un astfel de tip a fost declarat. De regul, pentru a da posibilitatea definirii obiectelor dinamice, orice clas se declar n forma: nume_tip-referinta : ^nume_clasa; nume_clasa =OBJECT.......END; Aici se face uz de excepia introdus de limbaj, de a declara o referin nainte de declararea tipului de date pe care l refer. Aceast permisiune asigur referine n interiorul obiectelor, la obiecte din propria clas i posibilitatea practic de a construi liste nlnuite de variabile i obiecte. De exemplu, dac se presupun declaraii de tip de forma: PPoint=^TPoint; TPoint=OBJECT.....END; PRational=^TRational; TRational=OBJECT....END; atunci este posibil s se declare variabile obiect de forma: PtrP1,PtrP2 : Ppoint; PtrRat1: PRational; Dup o astfel de declarare, compilatorul aloc spaiu (static) pentru variabilele referin. Este sarcina programatorului s aloce spaiul dinamic i s apeleze constructorii/ destructorii de iniializare/eliberare. n acest scop se utilizeaz procedurile New i Dispose, care au fost extinse astfel nct s accepte drept parametru i apelul la un constructor sau destructor. Mai mult, procedurile posed o replic sub form de funcie. Noua sintax a acestora se prezint astfel:

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    New(variabila_referinta); New(variabila_referinta, apel_constructor); Variabila_referinta := New(tip_referinta, apel_constructor); Dispose(variabila_referinta) Dispose(varaibila_referinta, apel_constructor); De exemplu, dac Init(x,y:Integer) este un constructor pentru cazul clasei Tpoint, se poate scrie: New (PtrP1); PtrP1^.Init (30,20); sau New (PtrP1, Init(30, 20)); sau PtrP1:=New (Ppoint, Init (30, 20));

    n acest mod se asigur o posibilitate n plus pentru evitarea omisiunii apelului constructorului. Similar stau lucrurile i cu eliberarea spaiului. Dac obiectele dinamice nu au spaiu extins, atunci eliberarea spaiului compact dinamic se va face prin apelul procedurii Dispose, n prima form; de exemplu, Dispose (PtrP1). Dac obiectul dinamic are spaiul extins, atunci clasa prevede i un destructor pentru acesta (destructor de spaiu extins). n acest caz se poate utiliza procedura Dispose n a doua form. De exemplu, dac se presupune clasa MatriceRat (exemplul_3), declarat n forma: MatriceRat=^TMatriceRat; TMatriceRat= OBJECTEnd; i declaraii de obiecte de forma: PtrA:TMatriceRat, se poate apela destructorul FreeExtMat n forma: Dispose (PtrA, FreeExtMat). Prin acest apel se execut mai nti destructorul, deci are loc eliberarea spaiului extins i apoi se elibereaz spaiul compact dinamic. Referirea unui obiect dinamic are forma referinta^ i accesul la membrii obiectelor va avea formele: referinta^.nume_metoda(argumente) referinta^.atribut Aa cum se pot construi masive de obiecte statice, tot aa se pot construi astfel de structuri avnd ca tip de baz referine la obiecte dinamice. Accesul la membrii obiectului k se va face sub forma: numearray[k]^.nume_metoda(argumente); numearray[k]^.atribut.

    10.3 Motenirea n Pascal

    Motenirea este o relaie de descenden ierarhic ntre clase, care ofer mecanismele necesare pentru ca o clas derivat s dobndeasc atributele

  • Obiecte n Pascal

    prinilor i s primeasc dreptul de acces la metodele acestora. Deoarece permite reutilizarea de cod, motenirea este aspectul definitoriu al metodei OOP.

    10.3.1 Aspecte de baz

    n limbajul Pascal, motenirea este implementat sub forma simpl, ceea ce nseamn c o clas nou poate fi derivat dintr-o singur clas printe (de baz). Pentru ca o clas s fie recunoscut ca baz a unei clase noi, declaraia acesteia trebuie s aib forma: nume_clasa_derivata = OBJECT(nume_clasa_baza) declaratii membri; End; n Pascal, clasa derivat poate s defineasc membri noi sau s utilizeze suprancrcarea unor metode ale printelui. Dac se are n vedere arborele de motenire, clasa derivat poate suprancrca metode ale oricrui ascendent. Totui, suprancrcarea n Pascal are unele limite fa de alte implementri. Operatorii limbajului nu pot fi suprancrcai, iar o metod nu poate fi suprancrcat de mai multe ori n cadrul aceleiai clase. Din punct de vedere sintactic i semantic, aceste limitri constituie neajunsuri, fiind necesar introducerea unor metode distincte pentru operaii formal identice, dar care acioneaz asupra unor obiecte de tipuri diferite. Dac este necesar ca ntr-o clas derivat, care suprancarc o metod a unui strmo, s fie referit explicit aceast metod, atunci, sintactic, numele clasei strmo trebuie s prefixeze numele metodei:

    nume_clasa_stramos.nume_metoda_supraincarcata( ) Dac ntr-un arbore de motenire o clas nu posed o anumit metod, dar o refer fr a preciza clasa strmo creia i aparine, compilatorul caut ascendent pn la prima apariie a ei. Limbajul prevede, de asemenea, o regul adecvat pentru asigurarea iniializrii corecte a obiectelor aparinnd unui arbore de derivare. Se cere ca fiecare clas s aib un constructor care s apeleze constructorul clasei printe pentru partea motenit i apoi s iniializeze atributele proprii (figura 10.9). O situaie similar, dar reciproc, este cea a destructorilor. Limbajul prevede c, n cazul obiectelor unei ierarhii, apelul ascendent al destructorilor este automat. Deci, dac o clas (final) posed un destructor pentru spaiul extins, atunci execuia acestuia declaneaz procesul de eliberare, din aproape n aproape, a spaiilor extinse motenite de la toi strmoii, prin execuia destructorilor acestora. Pentru ca mecanismul s funcioneze corect i n cazul n care exist clase strmo care nu posed spaiu extins, limbajul permite destructori cu corp vid, pe care compilatorul i genereaz automat la clasele respective. Pentru mai mult claritate, este recomandabil ca programatorul s defineasc destructori cu corp vid pe ramurile care nu conin cel puin un destructor propriu-zis.

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    O meniune aparte trebuie fcut pentru cazul obiectelor dinamice ale unei ierarhii de clase. Datorit polimorfismului, orice obiect este compatibil, la atribuire, cu oricare obiect al unui strmo. n aceste condiii, o referin la un obiect strmo poate conine adresa unui obiect descendent i apelul unei metode, de forma: PtrStramos^.Numemetoda ( ), introducnd un element de nedeterminare n privina obiectului de apel. Pentru astfel de cazuri, n limbajul Pascal s-a stabilit urmatoarea regul care se aplic n lipsa altor informaii adiionale: se apeleaz metoda clasei corespunzroare tipului referinei, dac o astfel de metod exist, sau metoda corespunztoare primului ascendent care o posed.

    a

    dcba

    cba

    InitInitInit

    Fig. 10.9 Motenirea i apelul

    Motenire

    Clasa A Clasa AClasa A

    Exemplu: 10.4. n ramura TXTYTZTW, definit n continuare, apare o

    procedur suprancrcat, p.

    PX=^TX; TX=OBJECT Procedure p END; PY=^TY; TY=OBJECT (TX) Procedure p END; PZ=^TZ; TZ=OBJECT (TY) Procedure q END; PW=^TW; TW=OBJECT (TZ) Procedure r END; Dac se declar obiectele dinamice PtrX:PX; PtrW:PW i se face atribuirea i apelul:

  • Obiecte n Pascal

    ..................

    PtrX:=PtrW; PtrX^.p; se va apela procedura p a clasei TX, ghidndu-se dup referina PtrX care este asociat acestei clase. Dac se declar PtrZ:PZ; PtrW:PW i se fac atribuirea i apelul: .................. PtrZ:=PtrW; PtrZ^.p; atunci se va apela metoda p a clasei TY, primul ascendent al clasei TZ, deintoarea referinei PtrZ, care posed aceast metod. Ipostazele incluse n compilator, dup regula de mai sus, permit legarea static a metodelor, care este simpl i eficient, dar care poate s nu fie convenabil n multe cazuri.

    10.3.2 Legarea dinamic. Metode virtuale

    Legarea dinamic se refer la metode suprancrcate, identice ca prototip, care sunt declarate ntr-o ramur a unei ierarhii de clase. n acest caz particular de suprancrcare, se spune c metoda este redefinit, avnd n vedere funcionalitatea nou (corpul nou) care i se asociaz. Este de dorit ca metoda s fie apelat cu obiectul a crui adres o conine referina de apel, fapt ce nu poate fi stabilit dect la momentul execuiei. Devine evident necesitatea ntiinrii compilatorului asupra acestei intenii, pentru a nu aplica regula legrii statice i, n consecin, pentru a genera codul necesar determinrii obiectului real i metodei de apelat la momentul execuiei. O astfel de tehnic de legare a unei metode cu obiectul dinamic este denumit dinamic (late binding). Declararea unei metode din aceast categorie se realizeaz prin declaratorul VIRTUAL, inclus n linia de definire a prototipului:

    procedure nume (parametri); VIRTUAL; function nume (parametri): tip_rezultat; VIRTUAL;

    Metodele redefinite sunt denumite virtuale. Dac o metod a fost declarat virtual ntr-o clas, atunci trebuie s fie declarat la fel n toate clasele derivate care au aceast clas la rdcin i redefinesc metoda n cauz. Totui, un descendent nu este obligat s redefineasc o metod virtual a unui ascendent, subnelegndu-se, n acest caz, c se aplic regula cutrii ascendente, dac un obiect al su o refer. O meniune aparte trebuie fcut cu privire la constructori i destructori. n primul rnd, trebuie remarcat faptul c obiectele care posed metode virtuale trebuie s fie iniializate prin constructor, dar constructorii nu pot fi declarai ca metode virtuale. Regula este de natur s asigure o corect iniializare, prin evitarea situaiilor necontrolabile de iniializare parial, posibile n cazul legrii dinamice. n al doilea rnd, se menioneaz, ca regul, posibilitatea de a virtualiza destructorii. Spre deosebire de constructori, virtualizarea destructorilor este, n

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    multe cazuri, absolut necesar, deoarece se recomand ca procedeu general. Ce se poate ntmpla n cazul n care destructorii nu sunt virtualizai rezult i din exemplul care urmeaz. Exemplu:

    10.5. Se presupune derivarea TATBTC i destructorul virtual D. Se declar un masiv de referine la obiecte de clas TA care se iniializeaz cu adresele unor obiecte. Se execut apoi tergerea obiectelor dinamice, cu apelul destructorului D, pentru a elibera spaiul extins al acestor obiecte.

    PA = ^ TA; TA = OBJECT ........................................

    Destructor D ; VIRTUAL; End; PB = ^ TB; TB = OBJECT (TA) ........................................

    Destructor D ; VIRTUAL; End; PC = ^TC; TC = OBJECT (TB) ........................................

    Destructor D; VIRTUAL; End; .............................................................

    p:array [0..2] of PA; .............................................................

    ..

    p[0]: = new (PB,); {contine obiect TB} p[1]: = new (PC,); {contine obiect TC} p[2]: = new (PA,); {contine obiect TA} .............................................................

    dispose (p[0], D); {apel destructor TB, TC} dispose (p[1], D); {apel destructor TC, TB, TA} dispose (p[2], D); {apel destructor TA} Se observ c p conine referine la diferite obiecte, n virtutea polimorfismului. tergerea obiectelor ale cror adrese sunt n componentele lui p implic o legare dinamic a destructorului potrivit. Astfel, pe baza regulii de apel automat al destructorilor n sens ascendent, se elibereaz corect, n fiecare caz, spaiul extins propriu i cel motenit. Dac D nu ar fi fost declarat virtual, deoarece p are tipul de baz corespunztor referinei la clasa TA, n fiecare caz s-ar fi apelat numai destructorul acestei clase, ceea ce ar fi nsemnat neeliberarea ntregului spaiu extins al obiectelor respective. Mecanismul metodelor virtuale este implementat prin intermediul tabelei de metode virtuale VMT (Virtual Methods Table) a clasei care se ataeaz prii de date a obiectelor din acea clas (figura 10.10).

  • Obiecte n Pascal

    Obiect 1 Obiect 2

    Fig. 10.10 Tabela de metode virtuale

    Atribut 1

    Atribut 2 . . .

    @VMT

    Atribut 1

    Atribut 2...

    @VMT

    Date de control

    @Metod virtual 1

    @Metod virtual 2

    .

    .

    .

    VMT

    Tabela de metode virtuale este ataat la obiect de unul din constructori, care este completat corespunztor de ctre compilator i este apelat nainte de apelul oricrei metode virtuale a obiectului respectiv.

    10.3.3 Motenirea i instanele Un tip obiect descendent dintr-un altul motenete, n particular, atributele

    ascendentului. El posed, deci, cel puin cmpurile ascendentului, plus, eventual, altele noi. O instan a unui tip ascendent poate fi, deci, atribuit cu o instan a descendentului (obiect_parinte:=obiect_fiu). O eventual atribuire invers este incorect, pentru c ar avea ca efect neiniializarea atributelor noi ale descendentului. De asemenea, n cazul unui transfer prin parametri valoare, o instan printe poate fi substituit cu una fiu.

    Dac, n schimb, obiectele conin spaiu extins i unuia dintre obiecte i este disponibilizat spaiul extins, atunci i cellalt i va pierde spaiul extins i, dac el i va apela destructorul, acesta va ncerca eliberarea unui spaiu de memorie inexistent. De asemenea, dac tipurile de obiecte conin metode virtuale, o atribuire nu este n general suficient n iniializarea corect a unei instane.

    O instruciune de atribuire utilizeaz dimensiunea unei instane pentru transferul de date. n cazul claselor ce conin metode virtuale, dimensiunea este coninut ntr-un cmp al VMT, deci poate fi cunoscut numai dup apelul constructorului respectiv. Efectul unei instruciuni de atribuire este, deci, consistent doar n funcie de dimensiuni, acestea putnd fi determinate numai dup apelul constructorului.

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Exemplu: 10.6. Lucrul cu metode virtuale

    program virt; uses crt; type parinte=object a,b:word; constructor init_p(a1,b1:word); function suma:word;virtual; end;

    fiu=object(parinte) c:word; constructor init_f(a1,b1,c1:word); function suma:word;virtual; end; var p:parinte; f:fiu; constructor parinte.init_p; begin a:=a1; b:=b1; end; function parinte.suma:word; begin suma:=a+b; end; constructor fiu.init_f; begin a:=a1; b:=b1; c:=c1; end; function fiu.suma:word; begin suma:=a+b+c; end; procedure afis; begin writeln('Instanta parinte a=',p.a,' b=',p.b, ' dimensiunea ',sizeof(p)); writeln('Instanta fiu a=',f.a,' b=',f.b,' c=',f.c,' dimensiunea ', sizeof(f)); readln; end;

    begin clrscr; fillchar(p,sizeof(parinte)+sizeof(fiu),#0); afis; {1} f.init_f(1,2,3); afis;{2} p:=f; afis;{3} p.init_p(4,5); afis;{4} p:=f; afis;{5} end.

  • Obiecte n Pascal

    Rezultatul execuiei programului

    {1} parinte fiu

    a=0 a=0

    b=0 b=0

    c=0

    dimensiune 0 dimensiune 0

    {2} parinte fiu

    a=0 a=1

    b=0 b=2

    c=3

    dimensiune 0 dimensiune 8

    {3} parinte fiu

    a=0 a=1

    b=0 b=2

    c=3

    dimensiune 0 dimensiune 8

    {4} parinte fiu

    a=4 a=1

    b=5 b=2

    c=3

    dimensiune 6 dimensiune 8

    {5} parinte fiu

    a=1 a=1

    b=2 b=2

    c=3

    dimensiune 6 dimensiune 8

    10.4 Proiectarea ierarhiilor de clase

    Tehnica OOP se bazeaz pe date i pe clasificarea corespunztoare a acestora. De aceea, pentru a asigura reutilizarea de cod, obiectivul principal al proiectrii este construirea unui arbore de motenire ct mai judicios. n continuare se vor face cteva recomandri de proiectare, ilustrate pe baza unui exemplu didactic de obiecte grafice, redat n detaliu la sfritul capitolului.

    10.4.1 Clase abstracte

    Dac n procesul de analiz se privilegiez datele, atunci primul lucru care trebuie pus n eviden sunt mulimile de obiecte care trebuie tratate. Pentru cazul obiectelor vizuale, acestea sunt: puncte, linii, dreptunghiuri, cercuri etc. n continuare trebuie cutate acele date (caracteristici) care sunt definitorii pentru diferitele tipuri de obiecte i trebuie puse n eviden acele elemente care sunt comune. Datele comune se constituie n clase i reprezint acele date care pot fi motenite. n cazul figurilor geometrice, se poate constata c orice obiect se identific printr-un punct de cordonate (x,y) reprezentnd nceputul liniei, colul stnga sus al dreptunghiului, centrul cercului etc, c orice figur presupune o curb de contur trasat cu o anumit culoare, c la figurile nchise se pune n eviden o suprafa care poate fi umplut (haurat i colorat) ntr-un anumit mod etc. Se poate uor constata c, aplicnd principiul gruprii datelor comune n clase, se ajunge n situaia de a obine clase pentru care nu are sens s se declare obiecte. Astfel, de exemplu, ar fi clasa care descrie curba de contur a obiectelor (Contur) sau cea care conine elementele definitorii pentru suprafaa interioar a obiectelor (Suprafaa). Astfel de clase se numesc abstracte (figura 10.11). Ele nu pot fi instaniate, adic nu pot genera obiecte de acest tip. Rolul lor n ierarhii este

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    acela de clase de baz care grupeaz date i metode comune. Din ele, prin specializare, se pot construi clase noi, care vor poseda caracteristicile clasei pe care o motenesc i, n plus, vor defini elemente (membri) specifice. Aa de exemplu, clasa Contur poate da natere unei clase Linie, de obiecte de tip linie dreapt, iar clasa Suprafaa conduce la clasele Dreptunghi i Cerc, ca obiecte cu suprafa specific. Clasele abstracte pot fi definite la diferite niveluri n arbore, fiind posibil ca o clas abstract s fie printe pentru o alt clas abstract mai specializat. De regul, o clas abstract este rdcin n orice ierarhie. Dei clasele abstracte nu se instaniaz, este permis s se declare referine ctre acestea. Acest lucru asigur polimorfismul i, la limit, o referin de clas rdcin poate recepiona adresa oricrui obiect din ierarhie i, n consecin, poate asigura tratarea dinamic a obiectelor polimorfice. Uneori, clasele abstracte sunt utilizate pentru a grupa clase care nu au date comune, dar particip mpreun la realizarea programelor. Aceste clase sunt att de generale nct, de regul, se reduc la un constructor vid i, eventual, la un destructor vid i virtual. Ele se justific prin aceea c, n virtutea polimorfismului, permit aplicarea unui cod comun i general la obiectele acestor clase, cum ar fi constituirea de liste eterogene.

    Definirea unei clase abstracte drept clas de baz a unei ierarhii conduce la posibilitatea de a utiliza aceeai clas pentru toate ierarhiile. Principiul este aplicat, n general, la construirea bibliotecilor de clase pe care limbajele orientate obiect le ofer. De exemplu, n Turbo Pascal, biblioteca denumit Turbo Vision are drept clas primordial pentru toate ierarhiile clasa TObject. Astfel se leag ntre ele diferitele ierarhii i se poate utiliza facilitatea de polimorfism.

    10.4.2 Definirea metodelor Dup conturarea claselor, din punctul de vedere al membrilor de tip dat,

    urmtoarea etap a proiectrii este definirea metodelor, innd cont de comportamentul dorit al diferitelor tipuri de obiecte. n cazul considerat, obiectele se creeaz, se afieaz, se ascund, i schimb culoarea de contur ori modul de umplere etc. (figura 10.11). n legtur cu definirea metodelor se fac urmtoarele precizri:

    Fiecare clas trebuie s posede un constructor. Dup modelul Turbo Vision, se recomand a fi denumit INIT. Constructorul unei clase trebuie s apeleze constructorul clasei printe, pentru a se asigura iniializarea prii motenite.

    Fiecare clas care utilizeaz alocarea dinamic pentru spaiu extins trebuie s posede un destructor, denumit DONE, declarat virtual.

    Vor fi declarate virtuale, la nivelul claselor strmo, toate metodele care urmeaz s fie redefinite n clasele derivate. Aceste metode trebuie s fie redeclarate ca virtuale n toi descendenii.

    Dac o clas instaniabil conduce la obiecte vizuale (grafice, texte), atunci clasa trebuie s posede o metod proprie de afiare (se spune c obiectele se

  • Obiecte n Pascal

    autoafieaz). Metoda de afiare se recomand s fie definit ca virtual, pentru a se asigura o legare dinamic adecvat.

    Pentru a asigura satisfacerea deplin a principiului abstractizrii i ncapsulrii datelor, se recomand utilizarea seciunii PRIVATE pentru datele specifice clasei i care nu intr direct n interfa. n acest sens trebuie prevzute, pentru fiecare cmp, o metod de consultare i o metod de modificare a valorii.

    Deoarece programele realizate prin tehnica OOP sunt de talie mare, se recomand utilizarea memoriei dinamice, care trebuie eliberat sistematic, eventual prin destructori adecvai.

    10.4.3 Tratarea erorilor

    n realizarea metodelor unei clase apar, de regul, dou tipuri de erori: de domeniu i de alocare. Erorile de domeniu sunt generate de nerespectarea domeniului de definire a metodei (de exemplu, pentru o clas stiv, operaiile de citire i tergere nu sunt definite n cazul n care lista este vid). Erorile nu sunt tratate de limbaj, fiind sarcina programatorului s prevad mecanisme adecvate de comunicare ntre metodele claselor i utilizatorul acestora. Dup agentul care provoac situaiile de eroare, se pot aplica, n general, dou strategii: a) Dac eroarea este determinat de starea obiectului curent, adic de obiectul cu care urmeaz s se apeleze o anumit metod, atunci este detectabil nainte de apel. Clasa prevede metode de detecie, ca funcii booleene, pe fiecare tip de eroare sau o funcie unic pentru a sesiza prezena erorii. Obiectul curent va utiliza o funcie de detecie adecvat i va proceda n consecin, adic va apela sau nu metoda respectiv. De exemplu, pentru un obiect de tip list, o funcie Empty poate testa dac pointerul pentru capul listei are valoarea NIL, ntorcnd valoarea True, dac lista este vid sau False, n caz contrar.

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Figura x, y

    EsteVizibil Culoare INIT AFISEAZA ASCUNDE ARIE SCHIMBACULOARE

    Punct Contur AFISEAZA ASCUNDE

    TipLinie GrosimeLinie INITDEFAULT SCHIMBACONTUR

    Linie Suprafata

    XSfarsit YSfarsit Init AFISEAZA ASCUNDE

    TipHasura CuloareUmplere INITDEFAULT SCHIMBAUMPLERE

    Dreptunghi Cerc

    Latime Inaltime INIT AFISEAZA ASCUNDE ARIE

    Raza INIT AFISEAZA ASCUNDE ARIE

    Fig. 10.11 Ierarhie de obiecte grafice

    b) Dac situaiile de eroare sunt datorate strii altor obiecte, care se primesc ca parametri n metoda aplicat, atunci strategia anterioar nu este aplicabil, deoarece numai metoda n cauz este n msur s sesizeze astfel de cazuri prin testarea parametrilor si. n consecin, modul n care s-a terminat execuia metodei se transmite ca o informaie apelatorului. Ea trebuie tratat ca o informaie global metodei sau chiar clasei, deoarece este independent de obiectul cu care s-a apelat metoda. Avnd n vedere ncapsularea claselor n uniti de program, astfel de informaii pot fi valori ale unor variabile globale, declarate n seciunea INTERFACE. Variabila global poate fi de tip enumerativ, tip n care constantele definesc situaiile de eroare. O declarare pentru aceste elemente poate avea, de exemplu, forma:

  • Obiecte n Pascal

    INTERFACE Type TipError=(OK, ZeroNum, TooBigNum); Var classErr:TipError;

    La nceputul metodelor implicate, variabilele de eroare se pun pe constanta

    care semnific succes i, dup testrile parametrilor, se modific adecvat. Este sarcina apelatorului metodei ca, la rentoarcerea controlului din metod, s testeze dac execuia s-a realizat cu succes.

    Erori de alocare. Alocarea spaiului dinamic pentru obiecte sau a spaiului extins al acestora poate eua. O astfel de situaie conduce la abandonarea programului. Programatorul trebuie s construiasc un mecanism propriu de tratare a situaiei. El se bazeaz pe utilizarea variabilei HeapError, procedura Fail i posibilitatea de a iniializa o unitate. Se procedeaz astfel:

    n fiecare constructor sau metod care utilizeaz alocarea dinamic trebuie s se testeze valoarea referinei returnat de funcia sau procedura de alocare. Dac a aprut o situaie de eroare de alocare, procedura poate prevedea cod pentru a recupera eroarea, dac acest lucru este posibil sau poate s ncheie n ordine execuia apelnd procedura Fail. De exemplu:

    Constructor TA.Init; Begin

    ....................................................

    new (Ptr1); {alocare de spatiu dinamic} new(Ptr2);

    ....................................................

    if (Ptr1=Nil) or (Ptr2=Nil). Then begin {cod pentru recuperare} sau {cod de terminare + TA.DONE + Fail;} end; {continuare constructor} End; n partea de implementare a unitii de program a clasei se definete o funcie proprie, avnd un argument de tip WORD, care este utilizat n locul funciei standard ce se apeleaz n caz de lips de spaiu: {$F+} {adresare far} Function fallocerr (a:Word): Integer; Begin fallocerr:=1 End; n partea de iniializare a unitii de program se introduce secvena:

  • Programarea calculatoarelor Tehnica programrii n limbajul Pascal

    Begin HeapError:=@fallocerr; End. n acest mod se nlocuiete funcia spre care puncteaz variabila HeapError, care ntoarce valoarea zero n caz de lips de spaiu, cu o funcie proprie care returneaz unu. Aceasta face ca sistemul s continue execuia programului i n cazul de eroare de spaiu, fcnd posibil tratarea proprie a situaiei.

    10. OBIECTE N PASCAL10.1 Modelul de date orientat pe obiecte10.2 Clase i obiecte n Pascal10.2.1 Specificarea claselor10.2.2 Utilizarea obiectelor10.2.3 Constructori i destructor+10.2.4 Utilizarea obiectelor dinamice

    10.3 Motenirea n Pascal10.3.1 Aspecte de baz10.3.2 Legarea dinamic. Metode vir10.3.3 Motenirea i instanele

    10.4 Proiectarea ierarhiilor de clase10.4.1 Clase abstracte10.4.2 Definirea metodelor10.4.3 Tratarea erorilor


Recommended