PASCAL - Programarea orientată pe Obiecte

34
12. 12. Obiecte Obiecte Pascal ( Pascal ( tipul tipul Object) Object) Programare Programare Orientat Orientat ă ă Obiect Obiect C_ C_ 15 15 / 18.01.20 / 18.01.20 13 13 Programarea Programarea Orientată Orientată Obiect Obiect ( Oop Oop) permite obţinerea unor programe structurate, modulare şi abstracte, bazându-se pe următoarele concepte: Î Î ncapsularea ncapsularea :unificarea atributelor (câmpurilor) cu operaţiile (metodele) într- un tot unitar numit obiect (tipul Object); Mo Mo ş ş tenirea tenirea :proprietatea de a păstra câmpurile şi metodele definite pentru un strămoş, prin tranzitivitate, dând posibilitatea de a construi o ierarhie de obiecte descendente plecând de la un obiect de bază; Polimorfismul Polimorfismul :numele unei acţiuni (al unei metode), poate fi reutilizat într-o ierarhie, pentru a redefini operaţia corespunzătoare obiectului definit.

description

Curs și exemple.

Transcript of PASCAL - Programarea orientată pe Obiecte

  • 12. 12. ObiecteObiecte Pascal (Pascal (tipultipul Object) Object) ProgramareProgramare OrientatOrientat ObiectObiect

    C_C_1515 / 18.01.20/ 18.01.201313

    ProgramareaProgramarea OrientatOrientat ObiectObiect (OopOop) permite obinerea unor programe

    structurate, modulare i abstracte, bazndu-se pe urmtoarele concepte:

    ncapsulareancapsularea :unificarea atributelor (cmpurilor) cu operaiile (metodele) ntr-un tot unitar numit obiect (tipul Object);

    MoMotenireatenirea :proprietatea de a pstra cmpurile i metodele definite pentru un strmo, prin tranzitivitate, dnd posibilitatea de a construi o ierarhie de obiecte

    descendente plecnd de la un obiect de baz;

    PolimorfismulPolimorfismul :numele unei aciuni (al unei metode), poate fi reutilizat ntr-oierarhie, pentru a redefini operaia corespunztoare obiectului definit.

  • ObiecteObiecte PascalPascal

    Vom nelege prin (tipul) Obiect (Object) o structur de date cu numr fix de componente care pot fi:

    Cmpuri:care definesc caracteristicile obiectului (aflate ntr-un domeniu de definiie), declarate ca i la tipul nregistrare (Record);

    Metode:prin care se definesc aciunile (operaiile), declarate prin antete de subprograme (funcii i proceduri);

    Declararea (definirea) unui obiect se face astfel:Type = ObjectObject

    {; }{;}

    End;End;

    Exemplu:Type Punct = ObjectObject

    x,yx,y : Real; : Real; { { CoordCoord. . x,yx,y ale ale punctuluipunctului }}Procedure Cit;Procedure Cit; { Cit. { Cit. coordcoord. . punctuluipunctului }}Function Function Dist(P:Punct):RealDist(P:Punct):Real; ; { Dist. { Dist. pnpn la pct. P }la pct. P }

    End;End;

    Observaie. Metodele au acces direct la componentele (cmpurile) obiectului, decinu mai este necesar parametrizarea lor.

  • ObiecteObiecte PascalPascal

    Definirea metodelor se realizeaz ulterior (ca i la directiva Forward) prciznd numeleobiectului, punct i numele metodei al crei bloc urmeaz s fie declarat:

    Procedure . [()];...

    End;respectiv

    Function . [():];...

    End;

    Exemplu:Procedure Procedure Punct.CitPunct.Cit;;Begin Begin

    Write (' Write (' x,yx,y : '); : '); ReadlnReadln ((x,yx,y) ) End;End;Function Function Punct.DistPunct.Dist;; { ({ (P:Punct):RealP:Punct):Real; ; Dist. Dist. pnpn la pct. Pla pct. P }}Begin Begin

    Dist := Dist := Sqrt(Sqr(xSqrt(Sqr(x--P.x)+Sqr(yP.x)+Sqr(y--P.yP.y)) )) End;End;

    Observaie. Lista parametrilor formali i tipul funciei pot fi omise, deoarece ele au fost deja definite n antetul de delarare a metodei din cadrul obiectului.

  • ObiecteObiecte PascalPascal

    Declaraiile instanelor de tip obiect sunt asemntoare cu declaraiile de variabile respectiv de constante.

    Exemplu:ConstConst O : O : PunctPunct = (x:0; y:0); = (x:0; y:0); VarVar A,B : A,B : PunctPunct;;P : Array[1..10] Of P : Array[1..10] Of PunctPunct;;

    Referirea cmpurilor i a metodelor se efectueaz (ca i la variabilele de tip Record) fie utiliznd caracterul ., fie instruciunea With :

    Accesul la cmpuri: ... . ...... With Do ......

    Apelul metodelor: ... . [()] ...... With Do ...< Nume_Metod>[()]...unde ::=

    Exemplu:BeginBegin ... ... A.CitA.Cit; ; { { CitesteCiteste A(x,yA(x,y) }) }

    With B Do Cit; With B Do Cit; { { CitesteCiteste B(x,yB(x,y) }) }Writeln('AOWriteln('AO=',A.Dist(O):4:2); =',A.Dist(O):4:2); { { TipreTipretete AO }AO }With B Do With B Do Writeln('BOWriteln('BO=',Dist(O):4:2); =',Dist(O):4:2); { { TipreTipretete BO } ...BO } ...

    End.End.

  • ObiecteObiecte PascalPascal

    Un obiect poate conine (agregaagrega) alt obiect (vezi n exemplul urmtor):Program Program AgregareAgregare;;Type Type PunctPunct = = Object Object x, y : Real; x, y : Real; { { AgregatAgregat }}

    Procedure Init(x0,y0:Real);Procedure Init(x0,y0:Real);Procedure Print;Procedure Print;

    End;End;CercCerc = = Object Object CentruCentru : : PunctPunct; ; { { AgregantAgregant }}

    RazaRaza : Real;: Real;Procedure Procedure Init(C:PunctInit(C:Punct; ; r:Realr:Real););Procedure Print;Procedure Print;

    End;End;Procedure Procedure Punct.InitPunct.Init; Begin x:=x0; y:=y0 ; Begin x:=x0; y:=y0 End;End;Procedure Procedure Punct.PrintPunct.Print; Begin Write(' x = ',x:5:2,' y = ',y:5:2) End;; Begin Write(' x = ',x:5:2,' y = ',y:5:2) End;Procedure Procedure Cerc.InitCerc.Init; Begin ; Begin CentruCentru:=C; :=C; RazaRaza:=r End;:=r End;Procedure Procedure Cerc.PrintCerc.Print; Begin ; Begin Centru.PrintCentru.Print; Write(' r = ',Raza:5:2) End;; Write(' r = ',Raza:5:2) End;VarVar O : O : PunctPunct; C : ; C : CercCerc;;BeginBegin

    O.InitO.Init (3,4); (3,4); C.InitC.Init (O,5);(O,5);O.PrintO.Print; ; C.PrintC.Print; ; ReadlnReadln

    End.End.

  • ObiecteObiecte PascalPascal

    Unui obiect i se poate asociaasocia alt obiect printr-un pointer sau o referin la acesta:Program Program AsociereAsociere;;Type Type FacultateFacultate = Object= Object { { AsociatAsociat }}

    DenumireDenumire,,AdresaAdresa : String[20]; : String[20]; Procedure Init (Procedure Init (Den,Adr:StringDen,Adr:String););Procedure Print;Procedure Print;

    End;End;StudentStudent = Object= Object { { AsociantAsociant }}

    Nume_PrenNume_Pren : String[20]; : String[20]; FacultaFaculta :^:^FacultateFacultate;;Procedure Init (Procedure Init (Nume:StringNume:String; ; Pf:PointerPf:Pointer););Procedure Print;Procedure Print;

    End;End;Procedure Procedure Facultate.InitFacultate.Init; Begin ; Begin DenumireDenumire:=Den; :=Den; AdresaAdresa:=:=AdrAdr End;End;Procedure Procedure Facultate.PrintFacultate.Print; Begin ; Begin Writeln(Denumire,',',AdresaWriteln(Denumire,',',Adresa) End;) End;Procedure Procedure Student.InitStudent.Init; Begin ; Begin Nume_PrenNume_Pren:=:=NumeNume; ; FacultaFaculta:=Pf End;:=Pf End;Procedure Procedure Student.PrintStudent.Print; Begin ; Begin Writeln(Nume_PrenWriteln(Nume_Pren); ); Faculta^.PrintFaculta^.Print End;End;VarVar Pf :^Pf :^FacultateFacultate; s : Student;; s : Student;BeginBegin

    New(PfNew(Pf); ); Pf^.Init('FacPf^.Init('Fac. de . de Mate_Info','Cluj_NapocaMate_Info','Cluj_Napoca'); '); Pf^.PrintPf^.Print;;s.Init('Ionescus.Init('Ionescu Marcel',PfMarcel',Pf); ); s.Prints.Print; ; ReadlnReadln

    End.End.

  • ObiecteObiecte PascalPascal

    Exist dou metode speciale i anume Constructor (folosit pentru alocarea

    obiectelor dinamice i pentru iniializarea metodelor virtuale) i Destructor

    (utilizat la eliberarea obiectelor dinamice).

    O clasa poate conine mai muli constructori i (chiar i) mai muli destructori.

    Constructorul poate fi apelat explicit, sau pentru obiectele alocate dinamic chiar ca

    parametru n procedura New :

    NewNew((Adr_refAdr_ref,,ConstrConstr(());));

    Alocarea cu New se poate face i astfel:

    AdrAdr:=:=NewNew((Tip_refTip_ref,,ConstrConstr(());));

    Dealocarea se poate face fie explicit, fie prin procedura Dispose:

    DisposeDispose((Adr_refAdr_ref,,DestrDestr(());));

  • ObiecteObiecte PascalPascalProgramul anterior l vom modifica astfel:Program Program Constructor_DestructorConstructor_Destructor;;Type Type Ref_FacRef_Fac=^=^FacultateFacultate;;

    FacultateFacultate = Object= ObjectDenumireDenumire,,AdresaAdresa : String[20];: String[20];ConstructorConstructor InitInit ((Den,Adr:StringDen,Adr:String););Procedure Print;Procedure Print;DestructorDestructor LiberLiber;;

    End;End;Student = ObjectStudent = Object

    Nume_PrenNume_Pren : String[20];: String[20];FacultaFaculta : : PointerPointer;;ConstructorConstructor InitInit ((Nume:StringNume:String; ; Pf:PointerPf:Pointer););Procedure Print;Procedure Print;

    End;End;ConstructorConstructor Facultate.Facultate.InitInit; Begin ; Begin DenumireDenumire:=Den; :=Den; AdresaAdresa:=:=AdrAdr End;End;Procedure Procedure Facultate.PrintFacultate.Print; Begin ; Begin Writeln(Denumire,',',AdresaWriteln(Denumire,',',Adresa) End;) End;DestructorDestructor Facultate.Facultate.LiberLiber; Begin ; Begin Writeln(Writeln('Facultate'Facultate StearsaStearsa'') End;) End;ConstructorConstructor Student.Student.InitInit; Begin ; Begin Nume_PrenNume_Pren:=:=NumeNume; ; FacultaFaculta:=Pf End;:=Pf End;Procedure Procedure Student.PrintStudent.Print; Begin ; Begin Writeln(Nume_PrenWriteln(Nume_Pren););

    Ref_Fac(Faculta)^.PrintRef_Fac(Faculta)^.Print End;End;VarVar Pf :Pf :Ref_FacRef_Fac; s : Student; ; s : Student; BeginBegin

    NewNew(Pf,(Pf,InitInit('Fac('Fac. de . de Mate_Info','Cluj_NapocaMate_Info','Cluj_Napoca')); ')); Pf^.PrintPf^.Print;;s.s.InitInit('Ionescu('Ionescu Marcel',PfMarcel',Pf); ); s.Prints.Print;;DisposeDispose(Pf,(Pf,LiberLiber); ); ReadlnReadln

    End.End.

  • ObiecteObiecte PascalPascal

    Despre metode virtuale vom discuta mai trziu (noiunea de legare trzie o maiamnm).

    ntr-un modul (Unit Pascal) putem utiliza directivele standard Public(componentele obiectului sunt vizibile i accesibile) i Private (componentelesunt innacesibile din program) pentru a putea modifica protecia cmpurilor i a metodelor. Uzual, cmpurile sunt Private iar metodele sunt de tip Public. Aceasta realizeaz o ncapsulare a datelor, deci accesul nu mai este permis dectprin intermediul operaiilor definite prim metode.

    Un exemplu de program care utilizeaz un astfel de modul este urmtorul: Program Program Public_PrivatePublic_Private;;Uses Uses StudentiStudenti;;VarVar Pf :Pf :Ref_FacRef_Fac; s : Student;; s : Student;BeginBegin

    New(Pf,Init('FacNew(Pf,Init('Fac. de . de Mate_Info','Cluj_NapocaMate_Info','Cluj_Napoca')); ')); Pf^.PrintPf^.Print;;s.Init('Ionescus.Init('Ionescu Marcel',PfMarcel',Pf); ); s.Prints.Print;;Dispose(Pf,LiberDispose(Pf,Liber); ); Readln

    End.End.

  • ObiecteObiecte PascalPascalModulul corespunztor este redat n continuare: Unit Unit StudentiStudenti;;InterfaceInterface

    Type Ref_Fac=^Facultate;Facultate = Object

    PrivateDenumire,Adresa : String[20];

    PublicConstructor Init (Den,Adr:String);Procedure Print;Destructor Liber;

    End;Student = Object

    PrivateNume_Pren : String[20];Faculta : Pointer;

    PublicConstructor Init (Nume:String; Pf:Pointer);Procedure Print;

    End;ImplementationImplementationConstructor Facultate.Init; Begin Denumire:=Den; Adresa:=Adr End;Procedure Facultate.Print; Begin Writeln(Denumire,',',Adresa) End;Destructor Facultate.Liber; Begin Writeln('Facultate Stearsa') End;Constructor Student.Init; Begin Nume_Pren:=Nume; Faculta:=Pf End;Procedure Student.Print; Begin Writeln(Nume_Pren); Ref_Fac(Faculta)^.Print End;

    End.End.

  • ObiecteObiecte PascalPascal

    Relaia de derivare este cea mai puternic relaie dintre clase. Plecnd de la o clas de baz putem obine noi clase derivate pstrnd componentele claseide baz i adugnd noi componente (cmpuri i metode). Metodele se pot redefini conform necesitilor noii clase.

    De exemplu avnd clasa Student, putem construi clasele Student_Bursier, Student_Cminist, etc. adugnd noi atribute cum ar fi Bursa, respectivCminul, redefinid anumite operaii i eventual adugnd altele noi.

    Un obiect (descendent) poate s moteneasc de la un alt obiect (strmo) cmpurile i metodele acestuia printr-o declaraie de forma:

    Type =Type = Object Object ((StrmoStrmo)){{; }}{{;}}

    End;End;Tipul descendent pstreaz componentele strmoului, fiind necesar doardefinirea noilor componente (noi cmpuri sau noi metode). Acest nou tip obiectpoate la rndul sau s fie strmo (tip definitor) pentru alt tip obiect (motenireafiind tranzitiv, adic toate componentele strmoului vor fi retransmise), dndposibilitatea formrii unei ierarhii.

  • ObiecteObiecte PascalPascalExemplu:

    ......Type Type CercCerc = Object= Object ((PunctPunct) ) {{CentrulCentrul cerculuicercului ((x,yx,y) se ) se momotenetenetete de la de la PunctPunct}}

    r : Real; r : Real; { { RazaRaza cerculuicercului }}......

    Function Function Aria:RealAria:Real; ; { { Aria Aria }}Function Function Lung:RealLung:Real; ; { { LungimeaLungimea }}

    ......End;End;

    VarVar ... ... C:CercC:Cerc; ... ; ... P:PunctP:Punct;;BeginBegin ......

    With C Do ... x ... y ... With C Do ... x ... y ... Dist(PDist(P) ... ) ... ......

    End.End.

    n exemplul de mai sus x i y reprezint coordonatele centrului cercului C, iarDist(P) distana de la centrul acestuia pn la punctul P, acestea fiind motenitede la Punct. Acest exemplu nu este poate cel mai nimerit, deoarece Cerculeste un (fel de) Punct cu o raz nu este foarte convingtor! Cu toate acestea, muli programatori prefer relaia de derivare, fiind mai puternic, chiar dac s-ar potrivi mai bine din punct de vedere didactic alt relaie pentru aceste douclase (de exemplu agregare: Cercul are un Punct i o raz).

  • ObiecteObiecte PascalPascaln cadrul unei ierarhii compatibilitatea este valabil doar de jos n sus, adicunuiunui strmostrmo i se i se poatepoate atribuiatribui un descendentun descendent ((sursasursa trebuietrebuie ss acopereacoperedestinadestinaiaia).).

    Exemplu:VarVar ... C,C1,C2:Cerc; ... ... C,C1,C2:Cerc; ... P:PunctP:Punct;;BeginBegin ......

    P:=C;P:=C; { P := { P := CentrulCentrul cerculuicercului (C) }(C) }... C1.Dist(C2) ... ... C1.Dist(C2) ... { { DistanDistanaa dintredintre centrelecentrele cercurilorcercurilor C1 C1 ii C2 }C2 }......

    End.End.

    Se poate observa n exemplul de mai sus c un cerc motenete metoda pentrude citire, dar aceasta permite doar citirea coordonatelor centrului cercului. Desigur c dorim s putem citi i raza acestuia. Mai mult, dorim s utilizmacelai nume i pentru a citi un cerc (P.Cit - s citeasc coordonatele punctuluiP, iar C.Cit s citesc pe lng coordonatele centrului i raza cercului C). naceste condiii, vom fi nevoii s redefinim metoda Cit. De asemenea, metodaC.Dist(P) dorim s calculeze distana de la punctul P la cercul C egal cu distana de la P la centrul cercului minus raza acestuia. Aa cum se poate vedean exemplul urmtor vom apela la conceptul de polimorfism, care permite uneimetode s reacioneze diferit n funcie de obiectul asupra cruia acioneaz.

  • ObiecteObiecte PascalPascalProgram Program PolimorfismPolimorfism; ; Type Type PunctPunct = Object x, y : Real;= Object x, y : Real;

    Procedure Cit;Procedure Cit;Function Function Dist(P:Punct):RealDist(P:Punct):Real; ;

    End;End;Procedure Procedure Punct.CitPunct.Cit;; Begin Write (' Begin Write (' x,yx,y : '); : '); ReadlnReadln ((x,yx,y) ) End;End;Function Function Punct.DistPunct.Dist;; Begin Dist:=Begin Dist:=Sqrt(Sqr(xSqrt(Sqr(x--P.x)+Sqr(yP.x)+Sqr(y--P.yP.y)) End;)) End;

    Type Type CercCerc = Object (= Object (PunctPunct) r : Real;) r : Real;Procedure Cit;Procedure Cit;Function Function Dist(P:Punct):RealDist(P:Punct):Real; ;

    End;End;Procedure Procedure Cerc.CitCerc.Cit; Begin ; Begin Punct.CitPunct.Cit; Write (' r : '); ; Write (' r : '); ReadlnReadln (r) End;(r) End;Function Function Cerc.DistCerc.Dist; Begin Dist:=; Begin Dist:=Punct.Dist(P)Punct.Dist(P)--rr End;End;

    VarVar A, M : A, M : PunctPunct; C : ; C : CercCerc;;BeginBegin

    Write('CWrite('C:'); :'); C.CitC.Cit; A:=C;; A:=C;Write('MWrite('M:'); :'); M.CitM.Cit;;With A Do With A Do WritelnWriteln ('Dist. punct:',Dist(M):6:2);('Dist. punct:',Dist(M):6:2);With C Do With C Do WritelnWriteln ('Dist. ('Dist. cerccerc :',Dist(M):6:2);:',Dist(M):6:2);

    WritelnWriteln ('MC:',M.Dist(C):4:2);('MC:',M.Dist(C):4:2); {Dist. de la M la {Dist. de la M la centrulcentrul cerculuicercului C }C }WritelnWriteln ('CM=',C.Dist(M):4:2)('CM=',C.Dist(M):4:2) { Dist. de la M la { Dist. de la M la cerculcercul C }C }

    End.End.

  • ObiecteObiecte PascalPascal

    n programul de mai jos, am definit metoda PeFig care decide dac un punct P este sau nu pe o figur geometric (Punct sau Cerc). Aceasta se poate rezolva, verificnd dac distana de la punct la figura dat este nul. Cercul motenetede la punct aceast metod, aa cum se poate vedea n continuare.

    Program Pr_Fct_NeVirtuala; Type Punct = Object x, y : Real;

    Procedure Cit;Function Dist(P:Punct):Real; { Ne Virtual}Function PeFig(P:Punct):Boolean;

    End;Cerc = Object (Punct) r : Real;

    Procedure Cit;Function Dist(P:Punct):Real; { Ne Virtual}

    End;Procedure Punct.Cit; Begin Write (' x,y : '); Readln (x,y) End;Function Punct.Dist; Begin Dist:=Sqrt(Sqr(x-P.x)+Sqr(y-P.y)) End;Function Punct.PeFig; Begin PeFig:=Dist(P)=0 End;Procedure Cerc.Cit; Begin Punct.Cit; Write (' r : '); Readln(r) End;Function Cerc.Dist; Begin Dist:=Punct.Dist(P)-r End;

  • Rezultatele referitoare la poziia relativ a punctului M fa de cercul C sunteronate deoarece metoda PeFig apeleaz metoda Punct.Dist n loc de Cerc.Dist, aa cum am dori (vezi tabelul urmtor):

    ObiecteObiecte PascalPascalVarVar M : M : PunctPunct; C : ; C : CercCerc;;Begin Begin Write (' M : '); Write (' M : '); M.CitM.Cit; Write (' C : '); ; Write (' C : '); C.CitC.Cit;;If If CC..PeFigPeFig(M(M)) Then Then WritelnWriteln(' M (' M esteeste pepe cerccerc ')') { { Cerc.DistCerc.Dist. . ?? }}

    Else Else WritelnWriteln(' M nu (' M nu esteeste pepe cerccerc ');');If If M.PeFig(CM.PeFig(C)) Then Then WritelnWriteln(' M (' M esteeste in in centrucentru ')') { { Punct.DistPunct.Dist..!! }}

    Else Else WritelnWriteln(' M nu (' M nu esteeste in in centrucentru ');'); ReadlnEnd.End.

    M nu este pe cercM nu este in centru

    M este pe cercM este in centru

    Rezultate

    M : x,y : 3 4 C : x,y : 0 0 r : 5

    M : x,y : 3 4C : x,y : 3 4r : 3

    DateExemplul 2Exemplul 1Contra Exemple

  • Programul corectat este urmtorul:

    Program Program Pr_Met_VirtualaPr_Met_Virtuala; ; Type Type PunctPunct = Object x, y : Real;= Object x, y : Real;

    Constructor Constructor Cit;Cit;Function Function Dist(P:Punct):RealDist(P:Punct):Real; ; VirtualVirtual;; {!}{!}Function Function PeFigPeFig(P:Punct):Boolean(P:Punct):Boolean;;

    End;End;

    ObiecteObiecte PascalPascalPentru ca Ob.PeFig(P) s determine distana de punctul P la cercul Ob (dac Ob este cerc), respectiv distana de la punctul Ob la punctul P (dac Ob este punct) vom corecta programul anterior prin declararea funciei Dist ca funcie virtual, ceea ce permite determinarea metodei (care se aplic unui obiect) doar n fazade execuie a programului, nu la compilare, pe baza unei tabele de metodevirtuale, VMT, creat printr-o metod de tip Constructor. Deci, mai trebuie sdeclarm metoda Cit ca metod de tip Constructor .Mai subliniem faptul c la redefinirea metodelor virtuale, antetul i tipul funcieitrebuie s coincid, iar dac un strmo conine o metod virtual, atunci toatemetodele omonime ale descendenilor trebuie s fie virtuale. De asemenea maiprecizm c un constructor nu poate fi virtual.

  • CercCerc = Object (= Object (PunctPunct) r : Real;) r : Real;Constructor Constructor Cit;Cit;Function Function Dist(P:Punct):RealDist(P:Punct):Real; ; VirtualVirtual; ; {!}{!}

    End;End;Constructor Constructor Punct.CitPunct.Cit; Begin Write ('; Begin Write ('x,yx,y:'); :'); Readln(x,yReadln(x,y)) End;End;Function Function Punct.DistPunct.Dist; Begin Dist:=; Begin Dist:=Sqrt(Sqr(xSqrt(Sqr(x--P.x)+Sqr(yP.x)+Sqr(y--P.yP.y)))) End;End;Function Function Punct.Punct.PeFigPeFig; Begin ; Begin PeFigPeFig:=:=Dist(PDist(P)=0)=0 End;End;Constructor Constructor Cerc.CitCerc.Cit; Begin ; Begin Punct.CitPunct.Cit; ; Write('rWrite('r:'); :'); Readln(rReadln(r)) End;End;Function Function Cerc.DistCerc.Dist; Begin Dist:=; Begin Dist:=Punct.Dist(P)Punct.Dist(P)--rr End;End;VarVar M : M : PunctPunct; C : ; C : CercCerc;;BeginBeginWrite('MWrite('M:'); :'); M.CitM.Cit; ; Write('CWrite('C:'); :'); C.CitC.Cit;;If If CC..PeFigPeFig(M(M)) Then Then WritelnWriteln(' M (' M esteeste pepe cerccerc ')') { { CercCerc..DistDist }}

    Else Else WritelnWriteln(' M nu (' M nu esteeste pepe cerccerc ');');If If MM..PeFigPeFig(C(C)) Then Then WritelnWriteln(' M (' M esteeste in in centrucentru ')') { { PunctPunct..DistDist }}

    Else Else WritelnWriteln(' M nu (' M nu esteeste in in centrucentru '); '); Readln

    End.End.

    ObiecteObiecte PascalPascal

  • Urmtorul program citeste o list de obiecte format din cercuri i discuri, apoise va calcula preul pentru fiecare obiect n funcie de tipul lui astfel:

    pentru cerc n funcie de lungime iar pentru disc n funcie de arie.

    Program Program Lista_PolimorficaLista_Polimorfica;;Type Type Ob_bOb_b = Object = Object r:Realr:Real;;

    Constructor Constructor Cit(Mes:StringCit(Mes:String););Function Function Pret:RealPret:Real; Virtual;; Virtual;

    End;End;CercCerc = Object (= Object (Ob_bOb_b ))

    Constructor Cit;Constructor Cit;Function Function Pret:RealPret:Real; Virtual;; Virtual;

    End;End;Disc = Object (Disc = Object (Ob_bOb_b ))

    Constructor Cit;Constructor Cit;Function Function Pret:RealPret:Real; Virtual;; Virtual;

    End;End;

    ObiecteObiecte PascalPascal

  • Constructor Constructor Ob_bOb_b .Cit; Begin .Cit; Begin Write(MesWrite(Mes); ); Readln(rReadln(r) ) End;End;Function Function Ob_bOb_b ..PretPret; Begin ; Begin PretPret:=0 :=0 End;End;Constructor Constructor Cerc.CitCerc.Cit; Begin ; Begin Ob_b.Cit('RcOb_b.Cit('Rc:') :') End;End;Function Function Cerc.PretCerc.Pret; Begin ; Begin PretPret:=2*Pi*r :=2*Pi*r End;End;Constructor Constructor Disc.CitDisc.Cit; Begin ; Begin Ob_b.Cit('RdOb_b.Cit('Rd:') :') End;End;Function Function Disc.PretDisc.Pret; Begin ; Begin PretPret:=Pi*r*r :=Pi*r*r End;End;VarVar O:ArrayO:Array [1..10] Of ^[1..10] Of ^Ob_bOb_b; ; i,n:Bytei,n:Byte; ;

    Pc:^CercPc:^Cerc; ; Pd:^DiscPd:^Disc;;BeginBegin

    Write('nWrite('n:'); :'); Readln(nReadln(n); Randomize;); Randomize;For i:=1 To n DoFor i:=1 To n Do

    If If Odd(Random(iOdd(Random(i))))Then Begin Then Begin New(PcNew(Pc); ); Pc^.CitPc^.Cit; ; O[iO[i]:=Pc]:=Pc EndEndElse Begin Else Begin New(PdNew(Pd); ); Pd^.CitPd^.Cit; ; O[iO[i]:=Pd]:=Pd End;End;

    For i:=1 To n DoFor i:=1 To n Dowith with O[iO[i]^]^ DoDo

    Writeln(i:3,Writeln(i:3,PretPret:7:2); :7:2); Readln

    End.End.

    ObiecteObiecte PascalPascal

  • Acelai program poate fi modificat utiliznd tipul pointer pentru a memoraadresele obiectelor, situaie n care va fi nevoie de conversia pointer referinla obiect din clasa de baz. De asemenea, apelul constructorului se poate face direct la alocare aa cum se poate vedea n cele ce urmeaz.

    TypeType Ob_bOb_b = Object = Object End;End;

    CercCerc = Object (= Object (Ob_bOb_b ) ) End;End;Disc = Object (Disc = Object (Ob_bOb_b ) ) End;End;

    Type Type RObROb=^=^Ob_bOb_b;;VarVar O:ArrayO:Array [1..10] Of [1..10] Of PointerPointer; ; i,n:Bytei,n:Byte; ; Pc:^CercPc:^Cerc; ; Pd:^DiscPd:^Disc;;BeginBegin

    Write('nWrite('n:'); :'); Readln(nReadln(n); Randomize;); Randomize;For i:=1 To n Do If For i:=1 To n Do If Odd(Random(iOdd(Random(i))))

    Then Begin Then Begin New(Pc,CitNew(Pc,Cit);); O[iO[i]:=Pc End]:=Pc EndElse Begin Else Begin New(Pd,CitNew(Pd,Cit);); O[iO[i]:=Pd End;]:=Pd End;

    For i:=1 To n DoFor i:=1 To n DoWith With RObROb(O[i(O[i])])^^ DoDo

    Writeln(i:3,Pret:7:2)Writeln(i:3,Pret:7:2); ; ReadlnEnd.End.

    ObiecteObiecte PascalPascal

  • Conversia explicit pointer Rob se face automat la apelul unei proceduri saufuncii prin parametru actual parametru formal, aa cum se poate vedea ncontinuare realizat acest lucru prin procedura Print.

    Type Type RObROb=^=^Ob_bOb_b;;

    Procedure Procedure PrintPrint((RefRef::RobRob););BeginBegin

    With With Ref^Ref^ Do Writeln(Do Writeln(PretPret:7:2):7:2)End;End;

    VarVar O:ArrayO:Array [1..10] Of [1..10] Of PointerPointer; ; i,n:Bytei,n:Byte; ;

    Pc:^CercPc:^Cerc; ; Pd:^DiscPd:^Disc;;

    BeginBegin

    For i:=1 To n Do For i:=1 To n Do PrintPrint((O[iO[i]]););ReadlnReadln

    End.End.

    ObiecteObiecte PascalPascal

  • ObiecteObiecte PascalPascal

    Dac se dorete prelucrarea fiecrui obiect din list de ctre mai multesubprograme atunci acestea se pot pune ntr-un ir pentru ca mai apoi s fie apelatfiecare subprogram ( For j:=1 To m). n exemplul de mai jos se va apela proceduraPrintj pentru fiecare obiect Oi. Evident c era posibil i scrierea unei proceduriavnd ca parametru formal unul de tip Procedura (variant propus ca tem). {$F+}{$F+}Type Type RObROb=^=^Ob_bOb_b;;

    ProceduraProcedura = Procedure (= Procedure (Ref:RobRef:Rob););Procedure Procedure Pret_ROLPret_ROL(Ref:Rob(Ref:Rob); Begin With Ref^ Do Write(Pret/10:9:3) End;); Begin With Ref^ Do Write(Pret/10:9:3) End;Procedure Procedure Pret_EURPret_EUR(Ref:Rob(Ref:Rob); Begin With Ref^ Do Write(Pret/40:9:3) End;); Begin With Ref^ Do Write(Pret/40:9:3) End;Procedure Procedure Pret_USDPret_USD(Ref:Rob(Ref:Rob); Begin With Ref^ Do Write(Pret/30:9:3) End;); Begin With Ref^ Do Write(Pret/30:9:3) End;Const Const PrintPrint:Array[1..3] Of :Array[1..3] Of ProceduraProcedura=(=(Pret_ROL,Pret_EUR,Pret_USDPret_ROL,Pret_EUR,Pret_USD););VarVar OO:Array:Array [1..10] Of Pointer; [1..10] Of Pointer; i,j,n:Bytei,j,n:Byte; ; Pc:^CercPc:^Cerc; ; Pd:^DiscPd:^Disc;;BeginBegin

    For For ii:=1 To n Do Begin:=1 To n Do Begin

    For For jj:=1 To 3 Do :=1 To 3 Do Print[j]Print[j]((O[iO[i]]); ); WritelnWriteln End;End;ReadlnReadln

    End.End.

  • ObiecteObiecte PascalPascal

    Suprancrcarea (overloading), prin redefinirea unor funcii sau metode, permitealegerea la compilare-link_editare a funciei sau a metodei dorite prinsemntura acesteia, fr a mai putea alege la execuie.

    Polimorfismul permite ca la execuie s se decid ce metod s fie apelat, oferindo facilitate a metodelor din clase aflate n relaie de derivare. Prin polimorfismse execut aciuni diferite prin mesaje cu semnturi identice asupra obiectelor de tip diferit (obiecte din clase diferite rspund diferit la acelai mesaj).

    Dou obiecte sunt compatibile dac aparin aceleai clase (evident) dar i douvariabile de tip

    - pointer la clasa de baz, respectiv pointer la clasa derivat, - referin (pointer constant) la clasa de baz, respectiv referin la clasa derivat.

    Metodele unei clase pot fi:- Clasice metode legate static, la compilare-link_editare fiind fixat adresa de

    apel a metodei, fr posibilitatea de a o schimba la rularea aplicaiei,- Polimorifice metode legate dinamic, care permit ntrzierea deciziei referitoare

    la adresa de apel a metodei, pn la execuie.

  • ObiecteObiecte PascalPascal

    Legarea unei metode (binding), nelegnd prin aceasta conexiunea logic dintre o entitate i o proprietate a acesteia (corespondena dintre un mesaj trimis unuiobiect, adic ordinul de apel, i metoda care se execut ca rspuns la acesta) poate fi:

    - Timpurie (staticearly-binding) compilatorul i editorul de legturi vor fixaadresa metodei care se execut, fr ca aceasta s mai poat fi modificat peparcursul execuiei;

    - Trzie (dinamiclate-binding) compilatorul va construi un tablou de adreseale metodelor posibile de apel, iar determinarea adresei metodei dorite se vaefectua doar la execuie. n funcie valoarea pointerului spre clasa de baz, care poate conine i adresa unui obiect al clasei derivate, se va alege metodacorespunztoare.

    Implicit, o metod este legat static (early, la compilare), iar dac se dorete o legare dinamic (late, la execuie) se va declara virtual (prin scriereacuvntului virtualvirtual dup antetul metodei). O metod virtual a unei clase de baz, poate fi motenit ntr-o clas derivat sau poate fi redefinit (nlocuit -overriding).

    O metod se declar virtual n clasa de baz. Nu se poate declara virtual doarntr-o clas derivat.

  • ObiecteObiecte PascalPascal

    n exemplul urmtor construim o list de studenti care pot fi bursieri sau cminiti. Acestia primesc de la prini o anumit suma, vor cheltui pe distracii, dac este cazul, primesc burs sau pltesc cminul. Din suma rmasa daujumtate la prieteni i 10% pentru preotecia mediului.

    Vom obine din clasa Student dou clase derivate: Bursier i Cminist :

    StudentStudent

    BursierBursier CministCminist

    Program Studenti; Type Ps=^Student;

    Pb=^Bursier; Pc=^Caminist;StudentStudent = Object

    Nume : String[30];Par,Che : LongInt;Constructor Init (Ns:String; p,d:LongInt);Constructor Copy (s:Student);Procedure Tips; Virtual;Function Ramasi:LongInt; Virtual;Function Prieten:LongInt;Destructor Eliber; Virtual;Destructor Liber; Virtual;

    End;

    BursierBursier = Object (StudentStudent)Bursa : LongInt;Constructor Init(s:Student; b:LongInt);Procedure Tips; Virtual;Function Ramasi:LongInt; Virtual;Destructor Eliber; Virtual;Destructor Liber; Virtual;

    End;

    CaministCaminist= Object(Student)Camin : LongInt;Constructor Init(s:Student; c:LongInt);Procedure Tips; Virtual;Function Ramasi:LongInt; Virtual;Destructor Eliber; Virtual;Destructor Liber; Virtual;

    End;

  • ObiecteObiecte PascalPascal

    Constructor Student.Init; Begin Nume:=Ns; Par:=p; Self.Che:=d {!} End;Constructor Student.Copy; Begin Self:=s End;Procedure Student.Tips; Begin Writeln(Nume, Par:10,Che:10) End;Function Student.Ramasi; Begin Ramasi :=Par-Che End;Function Student.Prieten; Begin Prieten:=Ramasi Div 2 End;Destructor Student.Eliber; Begin Writeln(' St. e liber ',Nume); End;Destructor Student.Liber; Begin Writeln(' St. Liber ',Nume); End;Constructor Bursier.Init; Begin Copy(s); Bursa:=b End;Procedure Bursier.Tips; Begin Student.Tips; Writeln(Bursa:12,'+B') End;Function Bursier.Ramasi; Begin Ramasi := Par-Che+Bursa End;Destructor Bursier.Eliber; Begin Writeln(' +B. e liber ',Nume); End;Destructor Bursier.Liber; Begin Writeln(' +B. Liber ',Nume); End;Constructor Caminist.Init; Begin Copy(s); Camin:=c End;Procedure Caminist.Tips; Begin Student.Tips; Writeln(Camin:12,'-C') End;Function Caminist.Ramasi;Begin Ramasi := Par-Che-Camin End;Destructor Caminist.Eliber; Begin Writeln(' -C. e liber ',Nume); End;Destructor Caminist.Liber; Begin Writeln(' -C. Liber ',Nume); End;

  • ObiecteObiecte PascalPascal

    Function Protectie(s:Ps):LongInt; Begin Protectie := s^.Ramasi Div 10 End;Var s:Student; St:Array[1..10] Of Ps; i:LongInt; n:Byte;Begin Randomize; n:=5+Random(6);

    For i:=1 To n Do Begins.Init('S'+Chr(i+48),500000*Random(n)+100000,20000*(n-i)+100000);Case Random(99) Mod 3 Of

    0: St[i]:=New(Ps,Copy(s) ); { Simplu }1: St[i]:=New(Pb,Init(s,10000*i)); { + Bursa }2: St[i]:=New(Pc,Init(s,20000*i)); { - Camin }

    End End;For i:=1 To n Do With St[i]^ Do Begin Tips;

    Writeln(Ramasi:12,Prieten:10,Protectie(St[i]):10)End; Readln;For i:=1 To n Do

    If TypeOf(St[i]^)=TypeOf(Student ) Then Writeln ('St') ElseIf TypeOf(St[i]^)=TypeOf(Bursier ) Then Writeln ('+B') ElseIf TypeOf(St[i]^)=TypeOf(Caminist) Then Writeln ('-C'); Readln;

    For i:=1 To n DoIf Odd(i) Then Dispose (St[i],Eliber) Else Dispose (St[i],Liber); Readln

    End.

    Se observ c prin Self se poate referi obiectul curent, iar cu TypeOf se determintipul. MoMotenireatenirea multiplmultipl nefiind posibil, ncnc, nu putem obine o clascorespunztoare unui Student_Bursier_Cminist dect prin derivarea unui Bursiern Bursier_Cminist, sau din Caminist putem obine Cminist_Bursier.

  • ObiecteObiecte PascalPascal

    Program Program Clasa_AbstractaClasa_Abstracta;;Type Type AnimalAnimal = Object= Object

    VarstaVarsta: Byte;: Byte;Constructor Constructor Nasc(v:ByteNasc(v:Byte););Function Function Varsta_MedieVarsta_Medie: Byte;: Byte; Virtual;Virtual;Function Function TanarTanar: Boolean; : Boolean; Virtual;Virtual;

    End;End;UrsUrs = = Object(AnimalObject(Animal))

    Function Function Varsta_MedieVarsta_Medie: Byte;: Byte; Virtual;Virtual;End;End;

    LupLup = = Object(AnimalObject(Animal))Function Function Varsta_MedieVarsta_Medie: Byte;: Byte; Virtual;Virtual;

    End;End;

    Exist numeroase situaii cnd ntr-o ierarhie avem nevoie de o clas abstract ncare vom defini unele trsturi comune fr a avea nici o instant din clasarespectiv. Ea poate conine mai multe metode pure (nule) care vor fi redefinitentr-o clas derivat, clas care devine concret (i poate fi instaniat doar dactoate metodele pure au fost definite. n exemplul de mai jos, clasa Animal esteabstract, iar clasele Urs i Lup sunt concrete.

  • ObiecteObiecte PascalPascal

    Function Function Animal.TanarAnimal.Tanar; Begin ; Begin TanarTanar:=:=VarstaVarsta

  • ObiecteObiecte PascalPascal

    n concluzie, referitor la Programarea orientat obiect (OOP) :

    OOP este o metod de implementare n care:a) ObiecteleObiectele sunt elementele de baz, b) Orice obiect este o instan a unei claseclase, c) Clasele sunt legate (asociate) unele cu altele prin momoteniretenire.

    Un limbaj este orientat obiect dac:a) Utilizeaz obiecteobiecte, b) Oblig obiectele s aparin unei claseclase, c) Permite momotenireatenirea.

    Limbajul Pascal ofer noiunea de clas, prin care se pot forma ierarhii, deci putem vorbi de o programare orientat obiect (OOP).

  • ObiecteObiecte PascalPascal

    OOPOOP nseamn realizarea unor programe alctuite dintr-o mulime de obiecteobiecte care interacioneaz pentru a rezolva problema propus, ipermite reutilizarea elementelor descrise (a interfeei i a codului).

    Un obiectobiect are o starestare i un comportamentcomportament (operaii descrise n interfaaobiectului) aceste dou componente fiind definite prin dateledatele membrumembru(variabilevariabile de de instaninstan) i respectiv prin funcfunciileiile membrumembru (metodemetode).

    OOP utilizeaz ormtoarele concepteconcepte: clasa- implementarea unui TAD, obiectul- instana unei clase, metoda- mesajul prin care se asigur interfaa (operaiile).

  • ObiecteObiecte PascalPascal

    OOP are urmtoarele caracteristicicaracteristici (proprietproprietii) de baz: ncapsularea- gruparea datelor i a operaiilor definite pentru acestea,

    precum i protecia acestor date (ele neputnd fi accesate dect prinfunciile membru).

    motenirea- pstrarea elementelor (date i funcii ale) unei clase (de baz), cu definirea de noi elemente construind o nou clas (derivat), formnd n felul acesta ierarhii de clase. Motenirea poate fi i multipldac o clas motenete mai multe clase.

    polimorfism- redefinirea (suprancrcarea) operaiilor (funciilor). ntr-o ierarhie pot fi mai multe funcii cu acelai nume, deci va fi efectuatoperaia corespunztoare obiectului care o apeleaz. Determinareaoperaiei se poate face la compilare (legare static) sau la execuie(legare dinamic, prin funcii vituale).

    Observaii referitoare la metodele virtuale: ClaseleClasele care conin metodemetode virtualevirtuale trebuie s conin cel puin un constructor

    care nu poate fi virtualvirtual i trebuie apelat naintea oricrei metodemetode virtualevirtuale (pentruorice instaninstan).

    O O metodmetod virtualvirtual redefinit trebuie s fie i ea virtualvirtual i s aib acelai antetantet.

  • TemeTeme::

    a) a) FiindFiind date date ninitete ((oricteoricte) ) figurifiguri geometricegeometrice ((cerccerc, , ptratptrat, , dreptunghidreptunghi, , sausau triunghitriunghi) ) ss se se desenezedeseneze ii ss se se afiafiezeeze pentrupentrufiecarefiecare aria aria ii perimetrulperimetrul..

    b) Un b) Un muncitormuncitor pltepltetete 10% din 10% din salarsalar pentrupentru asigurareasigurare, , iariarsalariulsalariul se se calculeazcalculeaz astfelastfel: : numrulnumrul_de_ore_lucrate_de_ore_lucrate * 50.000 lei* 50.000 lei

    . . .. . . C_15C_15 / / 18.01.201318.01.2013 oraora 14:0014:00 SalaSala N. N. IorgaIorga (2/I)(2/I)SuccesSucces !!

    c) c) FiindFiind date date maimai multemulte produseproduse, , ss se se precizezeprecizeze pentrupentru fiecarefiecaredacdac esteeste scumpscump sausau expiratexpirat (se (se vorvor alegealege treitrei tipuritipuri care care ss diferedifereprinprin prepre mediumediu ii termentermen de de garangaranieie).).