Sunteți pe pagina 1din 14

CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

1. CONCEPTE DE BAZ ALE PROGRAMRII


ORIENTATE OBIECT

1.1. Introducere 1.4. ncapsularea informaiei


1.2. Abstractizarea datelor 1.5. Legarea dinamic (trzie)
1.3. Motenirea 1.6. Alte aspecte

1.1. INTRODUCERE
Termenul "OOP" ("Object Oriented Programming") desemneaz disciplina programrii
obiectuale (orientate-obiect). Aceast disciplin care are la baz ideea unificrii datelor cu
modalitile de prelucrare a acestora i manevreaz entiti reprezentate sub form de obiecte
(obiect = date + cod de tratare a acestor date).

Rezolvarea unei probleme se poate face pe 3 direcii:


Rezolvarea orientat pe algoritm (pe aciune), n care organizarea datelor este neesenial;
Rezolvarea orientat pe date, aciunile fiind determinate doar de organizarea datelor;
Rezolvarea orientat obiect, care combin tendinele primelor dou abordri.

Programarea obiectual ofer posibiliti de modelare a obiectelor, a proprietilor i a


relaiilor dintre ele, dar i posibilitatea de a descompune o problem n componentele sale
(soft mai mentenabil, adaptabil, reciclabil). Cteva exemple de limbaje de programare
orientat obiect: SIMULA(1965), SIMULA-2(1967), Smalltalk, C++, Java (n plus, Java
poate fi considerat un limbaj de programare orientat eveniment).

Facilitile oferite de programarea orientat obiect (conform lui Pascou) sunt:


1. abstractizarea datelor;
2. motenirea;
3. ncapsularea (ascunderea) informaiei;
4. legarea dinamic (trzie).

1.2. ABSTRACTIZAREA DATELOR


Obiectele sunt componente software care modeleaz fenomene din lumea real. n general, un
fenomen implic tipuri diferite de obiecte. Obiectele care reprezint aceeai idee sau concept
sunt de acelai tip i pot fi grupate n clase (concrete sau abstracte). Clasele implementeaz
tipuri de date (un tip de date nseamn o mulime de valori pentru care s-a adoptatat un anumit
mod de reprezentare i o muime de operatori care pot fi aplicai acestor valori), deci i
operatorii destinai manipulrii acestora: Clas = Date + Operaii.

PROGRAMAREA ORIENTATA OBIECT, CURS 3 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

De exemplu, programatorul i poate defini tipul (clasa) matrice i operatorii care pot fi
aplicai matricilor (* pentru nmulirea a dou matrici, + pentru adunarea a dou matrici, -
pentru scderea a dou matrici, etc). Astfel, el poate folosi tipul matrice n mod similar unui
tip predefinit:
matrice A, B;
matrice C=A+B;
Tipul unui obiect (ablon al obiectului) este o clas. O clas se caracterizeaz prin: numele
clasei, atribute, funcii i relaii cu alte clase.
Instana este un obiect dintr-o clas (A, B, C sunt obiecte, instane ale clasei matrice) i are
proprietile definite de clas. Pentru o clas definit, se pot crea mai multe instane ale
acesteia. Toate obiectele au o stare i un comportament. Starea unui obiect se refer la
elementele de date coninute n obiect i la valorile asociate acestora (datele membre).
Comportamentul unui obiect este determinat de care aciunile pe care obiectul poate s le
execute (metodele).

Atributele specificate n definiia unei clase descriu valoric proprietile obiectelor din
clas, sub diferite aspecte. Cele mai multe limbaje orientate obiect fac urmtoarea distincie
ntre atribute:
atribute ale clasei (au aceeai valoare pentru toate instanele clasei);
atribute ale instanei (variaz de la o instan la alta, fiecare instan avnd propria
copie a atributului).
n limbajul C++ atributele se numesc date membre. Toate datele membre sunt atribute
instan. Atributele de clas se pot obine n cazul datelor membre statice (aceeai adres de
memorare pentru orice instan a clasei).

Metode (funcii membre). La definirea unei clase se definesc i metodele acesteia (numite i
funcii membre). Fiecare obiect are acces la un set de funcii care descriu operaiile care pot fi
executate asupra lui. Metodele pot fi folosite de instanele clasei respective, dar i de
instanele altor clase (prin mecanismul motenirii).
Clasa conine att structurile de date necesare descrierii unui obiect, ct i metodele care pot fi
aplicate obiectului. Astfel, gradul de abstractizare este, mult mai ridicat, iar programele devin
mult mai uor de neles, depanat sau ntreinut.

La crearea unui obiect, alocarea memoriei se poate fi face static sau dinamic (cu ajutorul unor
funcii membre speciale, numite constructori). Eliberarea memoriei se realizeaz cu ajutorul
unor funcii membre speciale, numite destructori, n momentul ncheierii existenei obiectului
respectiv.

1.3. MOTENIREA
Motenirea este o caracteristic a limbajelor de programare orientate obiect, care permite
refolosirea codului i extinderea funcionalitii claselor existente. ntre dou clase pot exista
multe diferene, dar i multe asemnri. Este bine ca informaia comun unor clase s fie
specificat o singur dat (conceptul de clas/subclas, superclas/clas n OOP).
Mecanismul motenirii permite crearea unei ierarhii de clase i trecerea de la clasele generale
la cele particulare. Procesul implic la nceput definirea clasei de baz care stabilete calitile
comune ale tuturor obiectelor ce vor deriva din baz (ierarhic superioar)(figura 1.1.). Prin
motenire, un obiect poate prelua proprietile obiectelor din clasa de baz.

PROGRAMAREA ORIENTATA OBIECT, CURS 4 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

Clasa A reprezint clasa de baz (este o generalizare) i conine


informaiile comune (disponibile prin motenire i subclaselor
acesteia). A
Clasa B reprezint clasa derivat (este o particularizare, o specializare a
clasei A) care extinde funcionalitatea clasei de baz i conine
informaiile specifice.
S presupunem c A reprezint clasa mamiferelor (cu proprietile
B
caracteristice: nasc pui vii, au snge cald, i alpteaz puii, etc), iar B
reprezint clasa animalelor domestice. n momentul definirii clasei
derivate B, aceasta motenete toate caracteristicile clasei A, rmnnd Figura 1.1. Relaia
de specificat doar trsturile distinctive. clas de baz-clas
n acest caz, A este clas de baz, iar B clas derivat (subclas a derivat
clasei A).
Sau: B este clas, iar A este o superclas a clasei B.
Motenirea poate fi: unic sau multipl.

1.3.1. MOTENIREA UNIC

n cazul motenirii unice, fiecare clas are doar o superclas. Exist dou modaliti de
specializare a unei clase de baz:
introducerea de extra-atribute i extra-metode n clasa derivat (particulare doar clasei
derivate);
redefinirea membrilor n clase derivate (polimorfism).

1.3.2. MOTENIREA MULTIPL

n situaia motenirii multiple, o clas are mai multe superclase. Astfel, motenirea clasei va fi
multipl (rezultnd o structur de reea).

A A

B C D B C D

E F G H E F

Figura 1.2. Motenirea simpl (unic) Figura 1.3. Motenirea multipl

Motenirea multipl este util, dar poate crea ambiguiti (cnd pentru acelai atribut se
motenesc valori diferite). Exist mai multe strategii de rezolvare a conflictului (printele
cel mai apropiat, cel mai deprtat, etc.). Deasemenea, este posibil o motenire repetat, n
care o clas ajunge s moteneasc de la aceeai clas, pe drumuri diferite n reea (vezi figura
1.3., n care clasa E motenete de la aceeai clas A, pe drumurile A-B-E, A-C-E) . Aa cum
vom vedea n capitolele urmtoare, n aceste situaii, limbajul C++ ofer programatorului
dou strategii: 1) clasa E poate avea dou copii ale lui A, una pentru fiecare drum; 2) clasa E
are o singur copie, iar A este clas virtual de baz i pentru C i pentru B. Ideea motenirii
PROGRAMAREA ORIENTATA OBIECT, CURS 5 Autor: Diana tefnescu
CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

multiple poate duce la utilizarea unor clase pentru care nu exist instane, care s ajute doar
la organizarea structurii (reelei) de motenire. n plus, limbajul C++ permite un control
puternic asupra atributelor i metodelor care vor fi motenite.

1.4. NCAPSULAREA (ASCUNDEREA) INFORMAIEI


ncapsularea (ascunderea) informaiei reflect faptul c atributele instan i metodele unui
obiect l definesc doar pe acesta. Vom spune c metodele i atributele unui obiect sunt
private, ncapsulate n obiect. Interfaa cu obiectul relev foarte puin din ceea ce se petrece
n interiorul lui. Obiectul deine controlul asupra atributelor instan, care nu pot fi alterate de
ctre alte obiecte. Excepia de la aceast observaie o reprezint doar atributele de clas care
nu sunt ncapsulate, fiind partajate ntre toate instanele clasei. Aceast tehnic de plasare a
valorilor n datele membre private ale obiectului, reprezint un mecanism de ascundere a
datelor.
n limbajul C++ ncapsularea poate fi forat prin controlul accesului, deoarece toate datele i
funciile membre sunt caracterizate printr-un nivel de acces (rezultnd astfel o mare
flexibilitate). Nivelul de acces la membrii unei clase poate fi (figura 1.4.):

private: membrii (date i metode) public


la care accesul este private pot fi
protected Clasa A
accesai doar prin metodele clasei
(nivel de acces implicit); private
protected: aceti membri pot fi
accesai prin funciile membre ale
clasei i funciile membre ale clasei
derivate;
public: membrii la care accesul
este public pot fi accesai din orice
punct al domeniului de existen a clas
clasei respective; derivat Clasa B
friend: aceti membri pot fi
accesai prin funciile membre ale
funciei prietene specificate. Figura 1.4. Accesul la membrii unei clase
n limbajul C++, nivelul de acces poate preciza i tipul de motenire (capitolul 4).
Public, unde n clasa derivat nivelul de acces al membrilor este acelai ca n clasa de
baz;
Privat, unde membrii protected i public din clasa baz devin private n clasa derivat.

1.5. LEGAREA DINAMIC (TRZIE)


Obiectele unei clase printe trebuie cunoscute n momentul compilrii. Efectul combinat al
motenirii poate determina ca o anumit metod s fie specializat diferit (prin redefinire),
pentru subclase diferite. Polimorfismul reprezint comportamente diferite ale unei metode n
raport cu tipul unui obiect. Selectarea unei metode redefinite poate fi realizat n faza de
compilare (legarea iniial), sau n momentul execuiei (legare trzie). n limbajul C++,
legarea dinamic se poate realiza prin implementarea de:
funcii virtuale (pot fi redefinite polimorfic);
funcii virtuale pure (doar declarate, nu definite).

PROGRAMAREA ORIENTATA OBIECT, CURS 6 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

1.6. ALTE ASPECTE


Comunicarea ntre obiecte
n limbajele de programare orientate obiect, obiectele comunic ntre ele prin mesaje, ceea ce
conduce la accentuarea conceptului de ncapsulare. Un obiect poate stimula un altul s
activeze (declaneze) o metod, trimindu-i un mesaj. Dup primirea mesajului, metoda
respectiv este apelat cu parametrii furnizai, asigurnd comportarea corespunztoare a
obiectelor. Metodele sunt invocate prin trimiterea de mesaje. n limbajul C++ funciile
membre (metodele) sunt accesate n mod similar oricarei funcii, cu deosebirea c este
necesar specificarea obiectului cruia i corespunde metoda.

Pseudovariabile
Limbajele de programare orientate obiect posed dou variabile (numite pseudo-variabile)
care difer de variabilele normale prin faptul c nu li se pot atribui valori n mod direct, de
ctre programator. n general, pseudovariabilele sunt o form scurt pentru obiectul curent
i pentru clasa printe a obiectului curent. n limbajul C++ exist doar una din aceste
pseudovariabile, numit this (pointer ctre obiectul curent).

Metaclasele
Metaclasele reprezint clase de clase. O clas este, de fapt, o instan a unei metaclase.
Diferenele dintre clase i metaclase sunt:
Clasa definete caracteristici (atribute i metode) ale instanelor de acel tip. Metodele
pot fi folosite doar de obiectele clasei, nu i de nsi clasa (restricie).
Metaclasele furnizeaz un mijloc prin care variabilele clas pot fi implementate: n
unele limbaje OOP, variabilele clas sunt instanieri ale unei metaclase.

Limbajul C++ nu include explicit metaclasele, dar suport variabilele clas sub forma datelor
statice. Aa cum funciile membre obinuite sunt ncapsulate nuntrul fiecarei instane,
pentru o funcie membru static a unei clase, se folosete o singur copie, partajat de ctre
toate instanele clasei. O asemenea funcie nu este asociat unei anumite instane.

Persistena
Persistena reprezint timpul de via al unui obiect (ntre crearea obiectului i tergerea sa).
Instanele unei clase au un timp de via dat de execuia unei metode sau a unui bloc, de
crearea sau tergerea specificat explicit n program sau de durata ntregului program.
Persistena obiectelor este important n special n aplicaiile de baze de date.

Suprancarcarea operatorilor.
Limbajul C++ furnizeaz modaliti de suprancrcare a operatorilor (overloading): acelai
operator are semnificaii diferite, care depind de numrul i/sau tipul argumentelor.

nainte de a ilustra n detaliu fiecare concept al programrii orientate-obiect cu mijloacele


specifice acesteia, pentru mptimiii programrii procedurale (orientat pe algoritm), se
prezint urmtoarele exemple. Implementarea s-a realizat n limbajul C, neutilizndu-se
facilitile programrii obiectuale. Cu toate acestea, exemplele ilustreaz o serie de concepte
din POO, deci este destul de greoaie. Capitolele urmtoare vor convinge ct de mult este
simplificat aceast abordare prin utilizarea facilitilor oferite de POO.

PROGRAMAREA ORIENTATA OBIECT, CURS 7 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

Exemplul1:
Se definesc tipurile de date CERC_FIGURA i DREPTUNG_FIGURA, pentru lucrul cu figuri
geometrice. Operaiile care pot fi realizate asupra ambelor tipuri de date sunt calculul ariei si
afiarea informaiilor despre o figur geometric (cerc sau dreptunghi).

n fiierul cfigura.h se definesc tipurile de date i se declar prototipurile funciilor care


opereaz asupra lor.
n fiierul cfigura.c se implementeaz funciile pentru operarea asupra unei figuri
geometrice.
n fiierul figtst1.c se testeaz tipurile de date definite i operaiile asupra acestora.

/*
-------------------------------------------------------------------------------------------------------------
Fisierul cfigura.h Defineste tipurile de date pentru lucrul cu figuri geometrice in C
-------------------------------------------------------------------------------------------------------------
*/

#ifndef CFIGURA_H
#define CFIGURA_H

#define T_CERC 1
#define T_DREPTUNG 2
/* Defineste structurile de date pentru figuri */

typedef struct CERC_FIGURA


{ short tip; /* Tipul figurii (T_CERC) */
double x, y; /* Coordonatele centrului cercului */
double raza; /* Raza cercului */
} CERC_FIGURA;

typedef struct DREPTUNG_FIGURA


{ short tip; /* Tipul figurii (T_DREPTUNG) */
double x1, y1; /* Coordonatele coltului stanga sus */
double x2, y2; /* Coordonatele coltului dreapta jos */
} DREPTUNG_FIGURA;

/* definirea unei uniuni a doua structuri */


typedef union FIGURA
{ short tip; /* tipul figurii */
CERC_FIGURA cerc;
DREPTUNG_FIGURA dreptung;
} FIGURA;

/* Prototipuri functii */
double calcul_arie(FIGURA *p_figura);
void afis_figura(FIGURA *p_figura);
#endif /* #ifndef CFIGURA_H */

PROGRAMAREA ORIENTATA OBIECT, CURS 8 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

/*
-----------------------------------------------------------------------------------------------------------------
Fisierul cfigura.c Implementarea functiilor C care opereaza asupra figurilor geometrice
-----------------------------------------------------------------------------------------------------------------
*/

#include <stdio.h>
#include "cfigura.h"
#include <math.h>

/* Functia calcul_arie: Calculeaza aria figurii geometrice (cerc sau dreptunghi) */


double calcul_arie(FIGURA *p_figura)
{ double aria;
switch(p_figura->tip) /* calc. ariei in functie de tipul figurii (cerc sau dreptunghi) */
{
case T_CERC:
aria = M_PI * pow(p_figura->cerc.raza,2);
break;
case T_DREPTUNG:
aria = fabs(
(p_figura->dreptung.x2 - p_figura->dreptung.x1)*
(p_figura->dreptung.y2 - p_figura->dreptung.y1));
break;
default: printf("Fig. Necun. functiei de clacul al ariei!\n");
}
return aria;
}

/* Functia afis_figura Afiseaza informatiile despre figura */


void afis_figura(FIGURA *p_figura)
{ printf("Afisare: ");
switch(p_figura->tip)
{
case T_CERC:
printf("Cercul cu raza %f si centrul (%f, %f)\n",
p_figura->cerc.raza,p_figura->cerc.x, p_figura->cerc.y);
break;
case T_DREPTUNG:
printf("Dreptunghi cu colturile: (%f, %f) si (%f, %f)\n",\
p_figura->dreptung.x1,p_figura->dreptung.y1,
p_figura->dreptung.x2,p_figura->dreptung.y2);
break;
default: printf("Figura necunoscuta!\n");
}
}

/* Ambele functii primesc ca argument un pointer catre tipul FIGURA */

PROGRAMAREA ORIENTATA OBIECT, CURS 9 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

/*
------------------------------------------------------------------------------------------------------------
Fisierul figtst1.c Programul de test
------------------------------------------------------------------------------------------------------------
*/

#include <stdio.h>
#include "cfigura.h"

main()
{ int i;
FIGURA s[2]; /* vector cu 2 elemente de tip FIGURA */
/* Initializarea elementelor vectorului */
//un dreptunghi
s[0].tip=T_DREPTUNG;s[0].dreptung.x1 = 80.0;
s[0].dreptung.y1=30.0;s[0].dreptung.x2=120.0;s[0].dreptung.y2=50.0;
//un cerc
s[1].tip=T_CERC;s[1].cerc.x=200.0;
s[1].cerc.y=100.0;s[1].cerc.raza=50.0;
for(i = 0; i < 2; i++)
printf("Aria elementului de indice %d din vector (de tipul %d)
este= %f\n", i, s[i].tip,calcul_arie(&s[i]));
/* Afisarea informatiilor despre elementele vectorului */
for(i = 0; i < 2; i++) afis_figura(&s[i]);
return 0;
}

/*
Rezultatele obinute n urma execuiei:

Aria elementului [0] = 7853.981634


Aria elementului [1] = 5000.000000
Afisare: Cerc cu raza 50.000000 si centrul (100.000000, 100.000000)
Afisare: Dreptunghi cu colturile: (100.000000, 150.000000) si (200.000000, 100.000000)
Aria elementului de indice 0 din vector (de tipul 2) este= 800.000000
Aria elementului de indice 0 din vector (de tipul 2) este= 7853.981634
Afisare: Dreptunghi cu colturile: (80.000000, 30.000000) si (120.000000, 50.000000)
Afisare: Cercul cu raza 50.000000 si centrul (200.000000, 100.000000)

*/

Exemplul 2:
Exemplul 2 mbuntete implementarea anterioar.
n fiierul figobj.h se definesc tipurile de date CLASA (tip de date), OBIECT (instan a unei
clase) i MESAJ (pentru gestiunea mesajelor prin care comunic obiectele ntre ele). Tot n
acest fiier sunt declarate funciile pentru crearea unui nou obiect (n C++, din punct de
vedere al rolului, vor fi constructorii) i funciile de lucru asupra mesajelor.
n fiierul oricefig.h se definete clasa generic generic_figura, care conine date i
funcii comune tuturor figurilor.
n fiierul objutil.c sunt definite funciile utilitare C, pentru exemplul programrii
obiectuale.

PROGRAMAREA ORIENTATA OBIECT, CURS 10 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

n fiierele obj_cerc.c, respectiv obj_drep.c se implementeaz clasele cerc


(cerc_clasa), respectiv dreptunghi (drept_clasa), ambele fiind clase derivate din clasa
de baz generic_figura.
Fiierul fig_test.c testeaz implementarea OOP a figurilor geometrice cerc i dreptunghi.

/*
----------------------------------------------------------------------------------------------------------------
Fisierul figobj.h Fisier header cu definitiile figurilor
----------------------------------------------------------------------------------------------------------------
*/

#if !defined(FIGOBJ_H)
#define FIGOBJ_H

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>

typedef struct MESAJ


{ int id_mesaj; /* Identificator mesaj */
int (*mesaj_handler)(); /* Functie gestiune mesaj, pointer catre functie */
} MESAJ;

typedef struct CLASA


{ struct CLASA *p_clasa_baza; /* Pointer catre clasa de baza */
int marime; /* Marimea instantei */
int num_mesaje; /* Numarul mesajelor */
MESAJ *mesaje; /* Tabela de mesaje */
} CLASA;

typedef struct OBIECT


{ void *p_data; /* Data instanta */
CLASA *p_clasa; /* Pointer catre structura CLASA */
} OBIECT;

#define ALOC_DATA 1
#define AFIS 2
#define CALCUL_ARIE 3

/* Functii pentru crearea obiectelor */


OBIECT *nou_cerc(double x, double y, double raza);
OBIECT *nou_dreptung(double x1, double y1, double x2, double y2);

/* Functii pentru lucrul asupra mesajelor */


int send_mesaj(OBIECT *p_obj, int msgid, ...);
int clasa_mesaj(CLASA *p_clasa,OBIECT *p_obj,int msgid,
va_list argp);
void *aloc_mem(size_t octeti);
int get_offset(CLASA *p_clasa);

#endif
/* #if !defined(FIGOBJ_H) */
PROGRAMAREA ORIENTATA OBIECT, CURS 11 Autor: Diana tefnescu
CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

/*
----------------------------------------------------------------------------------------------------------------
Fisierul oricefig.c Clasa generica "generic_figura" : Date, functii comune tuturor
figurilor
----------------------------------------------------------------------------------------------------------------
*/

#include "figobj.h"
static int aloc_data(OBIECT *p_obj, va_list argp);

static MESAJ mesaje[] =


{
ALOC_DATA, aloc_data
};

CLASA generic_figura = /* Clasa structura de date */


{
NULL, /* fara clasa baza */
0, /* fara date comune */
sizeof(mesaje)/sizeof(MESAJ), /* cate mesaje */
mesaje /* tabela de mesaje */
};

/* Functia aloc_data Aloca memorie pentru un datele obiectului */


static int aloc_data(OBIECT *p_obj, va_list argp)
{
CLASA *p_clasa;
int marime = 0;

/* Determina suma marimilor datelor instantelor fiecarei clase */


for(p_clasa = p_obj->p_clasa, marime = 0;p_clasa != NULL;
p_clasa = p_clasa->p_clasa_baza)
marime += p_clasa->marime;

/* Aloca memoria necesara */


p_obj->p_data = aloc_mem(marime);
return 1;
}

/*
-------------------------------------------------------------------------------------------------------------
Fisierul: objutil.c Functii utilitare pentru exemplul programarii obiectuale in C
-------------------------------------------------------------------------------------------------------------
*/

#include "figobj.h"

/* Functia send_mesaj Mesaj catre un obiect prin transmiterea mesajului catre clasa */
int send_mesaj(OBIECT *p_obj, int msgid, ...)
{ int status; va_list argp; va_start(argp, msgid);

PROGRAMAREA ORIENTATA OBIECT, CURS 12 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

status = clasa_mesaj(p_obj->p_clasa, p_obj, msgid, argp);


va_end(argp); return(status);
}

/* Functia clasa_mesaj Cauta in tabele "mesaje" un anumit mesaj si apeleaza


"mesaj_handler" in cazul in care il gaseste */
int clasa_mesaj(CLASA *p_clasa,OBIECT *p_obj,int msgid,va_list argp)
{
int i, status; if(p_clasa == NULL) return 0;
if(p_clasa->mesaje != NULL)
{ for(i = 0; i < p_clasa->num_mesaje; i++)
if(p_clasa->mesaje[i].id_mesaj == msgid)
{
return ((*p_clasa->mesaje[i].mesaj_handler)(p_obj, argp));
}
/* Daca mesaj netratat, trimite-l clasei de baza */
status=clasa_mesaj(p_clasa->p_clasa_baza,p_obj,msgid,argp);
}
return(status);
}

/* Functia aloc_mem Alocarea memoriei */


void aloc_mem(size_t numbytes)
{ void *ptr;
if((ptr = calloc(1, numbytes)) == NULL)
{ fprintf(stderr,"Er.alocare ptr %d oct de memorie.", numbytes);
exit(1); }
return(ptr);
}

/* Functia get_offset O data a instantelor este concatenarea datelor tuturor claselor din
ierarhie. Functia calculeaza offset-ul (deplasarea) fata de inceputul datei unei anumite clase */
int get_offset(CLASA *p_clasa)
{ CLASA *p_ct;
int marimet = 0;
/* parcurgerea ierarhiei de clase */
for(p_clasa=p_clasa->p_clasa_baza; p_clasa != NULL;
p_clasa = p_clasa->p_clasa_baza) marimet += p_clasa->marime;
return marimet;
}

/*
-------------------------------------------------------------------------------------------------------------
Fisierul: obj_cerc.c Clasa cerc
-------------------------------------------------------------------------------------------------------------
*/
#include "figobj.h"
typedef double *P_DOUBLE;

typedef struct DATE_CERC


{ double x, y; /* Coordonatele centrului */
double raza; /* Raza cercului */
} DATE_CERC;

PROGRAMAREA ORIENTATA OBIECT, CURS 13 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

extern CLASA generic_figura; /* Clasa de baza */

static int calcul_arie(OBIECT *p_obj, va_list argp);


static int afis(OBIECT *p_obj, va_list argp);

static MESAJ mesaje[] =


{ CALCUL_ARIE, calcul_arie, AFIS, afis };

/* Structura de date "clasa" */


CLASA cerc_clasa =
{ &generic_figura, /* Ptr catre clasa baza */
sizeof(DATE_CERC), /* Date ptr cercuri */
sizeof(mesaje)/sizeof(MESAJ), /* Numar mesaje */
mesaje /* Tabela mesaje */
};

static int cerc_offset = -1; /* Offset pentru date cerc */

/* Functia nou_cerc Creza o instanta de tip cerc si o initializeaza */


OBIECT *nou_cerc(double x, double y, double raza)
{ OBIECT *p_obj; DATE_CERC *p_data;
p_obj = (OBIECT *) aloc_mem(sizeof(OBIECT));
p_obj->p_clasa = &cerc_clasa;
/* Trimitere mesaj si aloca memorie pentru date */
send_mesaj(p_obj, ALOC_DATA, 0);
/* offset to pentru datele cerc */
if(cerc_offset < 0)
cerc_offset = get_offset(&cerc_clasa);
p_data = (DATE_CERC *)((char *)p_obj->p_data+cerc_offset);
p_data->x = x; p_data->y = y; p_data->raza = raza;
return(p_obj);
}

/* Functia calcul_arie Calculul ariei cercului. */


static int calcul_arie(OBIECT *p_obj, va_list argp)
{ int status = 0; double *p_area;
DATE_CERC *p_data; /* Pointer catre date cerc */
p_data=(DATE_CERC*)((char*)p_obj->p_data+cerc_offset);
/* Val. pointer catre double cand raspunsul este returnat */
p_area = va_arg(argp, P_DOUBLE);
if(p_area != NULL)
{ *p_area=M_PI*p_data->raza*p_data->raza;status = 1; }
return(status);
}

/* Functia afis Afisare cerc */


static int afis(OBIECT *p_obj, va_list argp)
{ DATE_CERC *p_data;
/* Setare pointer catre cerc */
p_data=(DATE_CERC*)((char*)p_obj->p_data+cerc_offset);
printf("Afisare: Cerc cu raza %f si centrul (%f, %f)\n",
p_data->raza, p_data->x, p_data->y);
return 1;
}

PROGRAMAREA ORIENTATA OBIECT, CURS 14 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

/* --------------------------------------------------------------------------------------------------------------
Fisierul: obj_drep.c
--------------------------------------------------------------------------------------------------------------
*/

#include "figobj.h"

typedef double *P_DOUBLE;

typedef struct DATE_DREPT


{ double x1, y1; /* Coordonate colt stanga sus */
double x2, y2; /* Coordonate colt dreapta jos */
} DATE_DREPT;

extern CLASA generic_figura; /* Clasa baza */

static int calcul_arie(OBIECT *p_obj, va_list argp);


static int afis(OBIECT *p_obj, va_list argp);

static MESAJ mesaje[] =


{ CALCUL_ARIE, calcul_arie, AFIS, afis };

/* Structura de date "clasa" */


CLASA drept_clasa =
{ &generic_figura, sizeof(DATE_DREPT),
sizeof(mesaje)/sizeof(MESAJ),
mesaje
};

static int drept_offset = -1;

/* nou_dreptunghi */
OBIECT *nou_dreptung(double x1, double y1, double x2, double y2)
{ OBIECT *p_obj; DATE_DREPT *p_data;
p_obj = (OBIECT *) aloc_mem(sizeof(OBIECT));
p_obj->p_clasa = &drept_clasa;
send_mesaj(p_obj, ALOC_DATA, 0);
if(drept_offset < 0) drept_offset = get_offset(&drept_clasa);
p_data = (DATE_DREPT *)((char *)p_obj->p_data+drept_offset);
p_data->x1 =x1;p_data->y1 = y1;p_data->x2 = x2; p_data->y2 = y2;
return(p_obj);
}

/* calcul_arie */
static int calcul_arie(OBIECT *p_obj, va_list argp)
{ int status = 0; double *p_area; DATE_DREPT *p_data;
p_data = (DATE_DREPT *)((char *)p_obj->p_data+drept_offset);
p_area = va_arg(argp, P_DOUBLE);
if(p_area != NULL)
{*p_area=fabs((p_data->x2-p_data->x1)*(p_data->y2-p_data->y1));
status = 1; }
return(status);
}

PROGRAMAREA ORIENTATA OBIECT, CURS 15 Autor: Diana tefnescu


CAPITOLUL 1 Concepte de baz ale programrii orientate obiect

/* afis */
static int afis(OBIECT *p_obj, va_list argp)
{ DATE_DREPT *p_data;
p_data=(DATE_DREPT *)((char *)p_obj->p_data + drept_offset);
printf("Afisare: Dreptunghi cu colturile: "
"(%f, %f) si (%f, %f)\n",p_data->x1, p_data->y1,
p_data->x2, p_data->y2);
return 1;}

/*
----------------------------------------------------------------------------------------------------------------
Fisierul de test: fig_test.c Implementare OOP a fig. geometrice cerc si dreptunghi
----------------------------------------------------------------------------------------------------------------
*/

#include "figobj.h"

int main(void)
{ int i; double area; OBIECT *fig[3];
/* Creare figuri (elemente ale vectorului "fig" */
fig[0] = nou_cerc(100.0, 100.0, 50.0);
fig[1] = nou_dreptung(100., 150., 200., 100.);
/* Calcul arii */
for(i = 0; i < 2; i++)
{ send_mesaj(fig[i], CALCUL_ARIE, &area);
printf("Aria elementului [%d] = %f\n", i, area); }
/* "afisare" figuri */
for(i = 0; i < 2; i++)
send_mesaj(fig[i], AFIS);
return 0;
}

/*
Rezultatele execuiei:

Aria elementului [0] = 7853.981634


Aria elementului [1] = 5000.0000000
Afisare: Cerc cu raza 50.000000 si centrul (100.000000, 100.000000)
Afisare: Dreptunghi cu colturile: (100.000000, 150.000000) si (200.000000, 100.000000)
*/

PROGRAMAREA ORIENTATA OBIECT, CURS 16 Autor: Diana tefnescu

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