Documente Academic
Documente Profesional
Documente Cultură
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).
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.
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).
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
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.
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.
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).
/*
-------------------------------------------------------------------------------------------------------------
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 */
/* Prototipuri functii */
double calcul_arie(FIGURA *p_figura);
void afis_figura(FIGURA *p_figura);
#endif /* #ifndef CFIGURA_H */
/*
-----------------------------------------------------------------------------------------------------------------
Fisierul cfigura.c Implementarea functiilor C care opereaza asupra figurilor geometrice
-----------------------------------------------------------------------------------------------------------------
*/
#include <stdio.h>
#include "cfigura.h"
#include <math.h>
/*
------------------------------------------------------------------------------------------------------------
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:
*/
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.
/*
----------------------------------------------------------------------------------------------------------------
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>
#define ALOC_DATA 1
#define AFIS 2
#define CALCUL_ARIE 3
#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);
/*
-------------------------------------------------------------------------------------------------------------
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);
/* 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;
/* --------------------------------------------------------------------------------------------------------------
Fisierul: obj_drep.c
--------------------------------------------------------------------------------------------------------------
*/
#include "figobj.h"
/* 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);
}
/* 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: