Documente Academic
Documente Profesional
Documente Cultură
Cuprins:
1. Clase şi obiecte 3
2. Constructori şi destructori 10
3. Încapsulare şi compunere 14
4. Suprascrierea metodelor şi operatorilor 19
5. Moştenire 23
6. Polimorfism 28
2
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Lucrarea nr. 1
Clase si obiecte
1. Scopul lucrarii
2. Notiuni teoretice
Variabilele sau obiectele continute intr-o clasa poarta numele de date membru
(sau campuri), iar functiile continute intr-o clasa poarta numele de functii membru
(sau metode). Atat campurile, cat si metodele, pot sa fie sau nu accesibile din
exteriorul clasei. Specificarea membrilor accesibili din afara ai unei clase se face
folosind specificatorul de acces public, in vreme ce pentru membrii inaccesibili
trebuie folosit specificatorul private.
In mod implicit (deci in cazul in care nu se scrie niciun specificator de acces)
toti membrii clasei sunt inaccesibili (ceea ce inseamna ca specificatorul de acces
private este implicit). Motivul pentru acest comportament este acela ca scopul
claselor este de a grupa laolalta (asa cum am spus) toate datele si actiunile
necesare pentru a opera cu un anumit tip (sau clasa) de obiecte. Iar gruparea
aceasta se face in scopul simplificarii muncii programatorului prin divizarea aplicatiei
software in clase de obiecte care sunt bine separate unele de altele si pot comunica
intre ele doar in moduri bine stabilite (fara ca un obiect dintr-o clasa sa trebuiasca sa
3
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
cunoasca detalii interne legate de implementarea unui obiect dintr-o alta clasa).
Asadar, detaliile interne ale unei clase trebuie tinute “secrete” (private) fata de
utilizatorii clasei respective, lasand vizibile (public) doar acele actiuni la care trebuie
sa poata raspunde obiectele acelei clase in vederea operarii cu ele. Este o practica
buna, asadar, ca toate datele membre ale unei clase sa fie private, in vreme ce doar
o parte dintre metode sa fie public.
class NumeClasa {
private:
// date
// (si, eventual, unele metode)
…
int nr;
public:
// metode publice
// (actiuni ce pot fi realizate de catre obiectele clasei, sau
asupra lor)
…
void Scrie(int val);
int Citeste();
};
int NumeClasa::Citeste()
{
return nr;
}
NumeClasa numeObiect;
Crearea unui obiect apartinand unei clase mai poarta numele de instantiere a clasei
respective. Ulterior definirii lui, obiectul numeObiect poate fi folosit pentru a apela
metodele publice. De exemplu, i se poate seta valoarea interna scriind:
4
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
numeObiect.Scrie(7);
3. Desfasurarea lucrarii
3.1. Exemplu
+-+-+-+
| | |X|
+-+-+-+
| | | |
+-+-+-+
|X|O| |
+-+-+-+
In fiecare dintre cele 9 pozitii de pe tabla se va putea gasi una dintre urmatoarele 3
“piese”:
- nimic (spatiu)
- piesa “X” (X)
- piesa “O” (O).
Pentru fiecare pozitie de pe tabla vom folosi o valoare de tip numar intreg
(int), cu urmatoarea semnificatie:
0 → “ “ (spatiu)
1 → “X”
2 → “O”.
Prin urmare, cel mai natural e sa folosim o matrice de 3x3 elemente de tip numar
intreg.
5
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
#include <stdio.h>
#include <conio.h>
void main(void)
{
// Defineste tabla:
int t[3][3];
// Pune piese pe tabla:
t[0][0] = 0; t[0][1] = 0; t[0][2] = 1;
t[1][0] = 0; t[1][1] = 0; t[1][2] = 0;
t[2][0] = 1; t[2][1] = 2; t[2][2] = 0;
// Afiseaza tabla:
AfiseazaTabla(t);
getch(); // asteapta...
}
class TablaDeJoc {
private:
int t[3][3];
public:
void Afiseaza();
void PunePiesa(int l, int c, int p);
};
void TablaDeJoc::Afiseaza()
{
int l;
int c;
for (l=0; l<3; l++)
{
printf(“+-+-+-+\n”);
for (c=0; c<3; c++)
{
printf(“|”);
if (t[l][c] == 0) printf(“ “);
else if (t[l][c] == 1) printf(“X”);
else if (t[l][c] == 2) printf(“O”);
}
printf(“|\n”);
}
printf(“+-+-+-+\n”);
}
#include <stdio.h>
#include <conio.h>
class TablaDeJoc {
...
};
void main(void)
{
TablaDeJoc tabla;
tabla.PunePiesa(0, 0, 0); tabla.PunePiesa(0, 1, 0); tabla.PunePiesa(0, 2, 1);
tabla.PunePiesa(1, 0, 0); tabla.PunePiesa(1, 1, 0); tabla.PunePiesa(1, 2, 0);
tabla.PunePiesa(2, 0, 1); tabla.PunePiesa(2, 1, 2); tabla.PunePiesa(2, 2, 0);
tabla.Afiseaza();
getch();
}
8
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
3.2. Exercitii
(1) Sa se scrie si sa se ruleze cele doua programe folosind Visual C++. Notati
observatiile.
(2) Sa se modifice ambele programe astfel incat tabla sa nu mai fie de 3x3 pozitii, ci
de 4x4. Ce observati?
(3) Sa se modifice ambele programe rezultate la punctul (2) astfel incat variabila t sa
nu mai fie denumita t, ci x. Ce observati?
(6) Sa se separe codul sursa al programului de la punctul (5) in mai multa fisiere,
astfel incat clasa TablaDeJoc si functia main sa fie definite in fisiere diferite. La ce
este utila aceasta activitate?
Bibliografie
9
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Lucrarea nr. 2
Constructori si destructori
1. Scopul lucrarii
2. Notiuni teoretice
{
…
int x; // ← creare “obiect” x
...
} // ← distrugere “obiect” x
int *px;
px = new int; // ← creare “obiect” (*px)
…
delete px; // ← distrugere “obiect” (*px)
class NumeClasa {
10
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
private:
…
public:
NumeClasa(); // ← constructor fara parametri
NumeClasa(int parametru); // ← constructor un parametru
…
~NumeClasa(); // ← destructor
...
};
NumeClasa::NumeClasa()
{
...
}
NumeClasa::NumeClasa(int parametru)
{
…
}
NumeClasa::~NumeClasa()
{
...
}
...
3. Desfasurarea lucrarii
3.1. Exemplu
11
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
#include <stdio.h>
class TablaDeJoc {
private:
int t[3][3]; // ← camp
public:
TablaDeJoc(); // ← constructor implicit (i.e. fara parametri)
~TablaDeJoc(); // ← destructor
void Afiseaza(); // ← metoda
void PunePiesa(int l, int c, int p); // ← metoda
};
TablaDeJoc::TablaDeJoc()
{
int l, c;
for (l=0; l<=2; l++)
for (c=0; c<=2; c++)
t[l][c] = 0;
}
TablaDeJoc::~TablaDeJoc()
{
printf(“Bye! :-)\n”);
}
...
TablaDeJoc tabla;
Desi o clasa poata avea un singur destructor, ea poate avea mai multi
constructori. Diferentierea intre ei compilatorul o va face (la fel ca in cazul metodelor
si al functiilor obisnuite) prin intermediul numarului si tipului parametrilor. Sa vedem,
de exemplu, cum am defini un constructor pentru clasa TablaDeJoc care in loc sa
initializeze elementele tablei cu valoarea 0, sa le initializeze cu o valoare primita ca
parametru:
TablaDeJoc::TablaDeJoc(int p)
12
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
{
int l, c;
for (l=0; l<=2; l++)
for (c=0; c<=2; c++)
t[l][c] = p;
}
3.2. Exercitii
Bibliografie
13
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Lucrarea nr. 3
Incapsulare si compunere
1. Scopul lucrarii
2. Notiuni teoretice
class NumeClasa {
private:
int data;
public:
…
int CitesteData();
void ScrieData(int data);
};
int NumeClasa::CitesteData()
{
return data;
}
14
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
3. Desfasurarea lucrarii
3.1. Exemplu
3.1.1. Incapsulare
z = re + i* im
(Valorile re si im sunt numere reale, re fiind partea reala si im partea imaginara, iar i
este unitatea pe axa valorilor imaginare (fiind egal cu radacina patrata din (-1)).)
Prin urmare, pentru a putea opera cu un numar complex trebuie sa memoram doua
variabile -- partea imaginara si partea reala. In ceea ce priveste actiunile pe care sa
le putem face cu el, ne putem gandi la:
- accesarea partii reale si a partii imaginare (scriere/citire valori)
15
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
- calculul modulului
- calculul unghiului
- adunarea cu un alt numar complex
- inmultirea cu un alt numar complex
- etc.
#include <math.h>
class NrComplex {
private:
double re; // ← partea reala
double im; // ← partea imaginara
public:
// constructori:
NrComplex(); // ← constructor implicit
NrComplex(double re, double im); // ← constructor
// metode de acces:
double CitesteRe();
void ScrieRe(double re);
double CitestetIm();
voidScrieIm(double im);
// metode utilitare:
double Modul();
double Unghi();
void Aduna(NrComplex c);
void Inmulteste(NrComplex c);
...
};
NrComplex::NrComplex()
{
re = 0;
im = 0;
}
double NrComplex::CitesteRe()
16
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
{
return re;
}
double NrComplex::Modul()
{
return sqrt(re*re+im*im);
}
void NrComplex::Aduna(NrComplex c)
{
re += c.re;
im += c.im;
}
3.1.2. Compunere
class JocDeXsiO {
private:
TablaDeJoc tabla;
Jucator juc1;
17
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Jucatorjuc2;
public:
JocDeXsiO();
void Initializeaza();
void Joaca();
int RezultatJoc();
};
3.2. Exercitii
class Jucator {
private:
int tip; // 1 ← X; 2 ← O
public:
Jucator();
void StabilestePiese(int tip);
Piesa CitesteMutare(); // ← citeste de la tastatura mutarea
// ca numar de la 1 la 9
};
struct Piesa {
int l;
int c;
int tip;
};
Bibliografie
18
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Lucrarea nr. 4
1. Scopul lucrarii
2. Notiuni teoretice
c3 = c1+c2; // ← = 3 - i
19
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
si are rolul de a permite ca in corpul functiei operator+ (pe care il vom defini,
bineinteles, in afara corpului clasei NrComplex) sa putem accesa membrii privati re
si im ai obiectelor c1 si c2.
3. Desfasurarea lucrarii
3.1. Exemplu
class AfisorDeNumere {
public:
void Afiseaza(char x);
void Afiseaza(int x);
void Afiseaza(long x);
void Afiseaza(float x);
void Afiseaza(double x);
};
void AfisorDeNumere::Afiseaza(char x)
20
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
{
printf(“%d”, x);
}
...
void AfisorDeNumere::Afiseaza(float x)
{
printf(“%f”, x);
}
class NrComplex {
…
public:
NrComplex operator+ (NrComplex c);
NrComplex operator* (NrComplex c);
};
class NrComplex {
…
public:
friend NrComplex operator+ (NrComplex c1, NrComplex c2);
};
3.2. Exercitii
(2) Sa se scrie cate un program de test pentru fiecare dintre cele doua metode de
suprascriere a operatorilor “+” si “*” prezentate (pentru clasa NrComplex).
Bibliografie
22
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Lucrarea nr. 5
Mostenire
1. Scopul lucrarii
2. Notiuni teoretice
Clasele pot fi extinse prin combinarea lor (asa cum am aratat in lucrarea referitoare
la compunerea claselor), dar si prin mostenire. Mostenirea in programarea orientata
pe obiecte este operatia prin care dintr-o clasa de baza se obtine o clasa derivata.
Clasa derivata extinde functionalitatea clasei de baza, specializand-o. Clasa de baza
este mai simpla, mai generica, mai abstracta, in vreme ce clasa derivata este mai
complexa, mai specifica, mai concreta.
Prin mostenire toate elementele clasei de baza se regasesc in clasa derivata, iar la
acestea se pot adauga unele noi si se pot modifica comportamente existente.
Pentru a intelege ideea de mostenire, ne putem gandi la clasele de forme
geometrice cele mai cunoscute. Astfel, daca avem o clasa de baza numita, de
exemplu, FormaGeometrica, putem deriva din ea clase ca Triunghi, Patrulater si
Elipsa. (Si zicem ca aceste clase mostenesc clasa FormaGeometrica). De
asemenea, putem avea si clase ca Trapez si Paralelogram, ce mostenesc clasa
Patrulater. In plus, mai putem avea si alte clase, rezultand o ierarhie arborescenta
de genul urmator:
FormaGeometrica
∟Triunghi
∟Dreptunghic
∟Isoscel
∟Echilateral
∟Patrulater
∟Trapez
∟Paralelogram
∟Dreptunghi
∟Patrat
∟Elipsa
∟Cerc
Chiar daca poate intr-un program nu s-ar justifica decat in rare cazuri
23
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
construirea unei asemenea ierarhii de clase derivate unele din altele, ea ilustreaza
bine la nivel conceptual in ce consta mostenirea claselor. De exemplu, in arborele de
mai sus vedem ca clasa Patrat mosteneste clasa Dreptunghi, care la randul ei
mosteneste clasa Paralelogram, care la randul ei mosteneste clasa Patrulater, care
la randul ei mosteneste clasa FormaGeometrica. Este evident ca orice patrat este un
dreptunghi, iar orice dreptunghi este un paralelogram, iar orice paralelogram este un
patrulater, iar orice patrulater este o forma geometrica.
In general, atunci cand zicem ca orice obiect de tip B este si un obiect de tip A
inseamna ca B are aceleasi tip de caracteristici ca si A, plus unele detalii. Atfel spus,
clasa B mosteneste clasa A (sau, echivalent, clasa B este derivata din clasa A (care
este, deci, clasa de baza pentru B)).
Montenirea se realizeaza folosind o constructie C++ de genul urmator:
class B : public A {
...
};
apartinand clasei B se vor face mai intai initializarile specifice obiectelor clasei A
(caci in fond orice obiect din clasa B este un obiect din clasa A), dupa care se vor
putea adauga in constructorul clasei B alte initializari ce sunt necesare.
Daca se doreste, insa, apelarea dintr-un constructor al clasei B nu a
constructorului implicit, ci a unui constructor cu parametri, se poate proceda in felul
urmator:
class A {
…
public:
A(int x);
...
};
class B : public A {
…
public:
B(int x);
...
};
B::B(int x) : A(x)
{
// (eventual) alte initializari
...
}
int Arie()
{
return Dreptunghi::Arie();
}
3. Desfasurarea lucrarii
25
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Console Application”.
3.1. Exemplu
abstract
Animal ← clasa de baza
↓ - caracteristicile generale ale unui animal
Caine ← clasa derivata din clasa Animal
(si clasa de baza pentru clasa CaineAzor)
↓ - caracteristicile generale ale unui animal
↓ - caracteristici specifice cainilor
CaineAzor ← clasa derivata din Caine
- caracteristicile de baza ale unui animal
- caracteristici specifice cainilor
- caracteristici specifice lui Azor
concret
+---------------------------------------------------+
|+-----------------------------------+ Animal |
| | +--------------------+ Caine | |
| | | CaineAzor | | |
| | +--------------------+ | |
| +----------------------------------+ |
+---------------------------------------------------+
Aceasta diagrama arata foarte clar ca orice caine Azor este un caine, iar orice
caine este un animal. Pe de alta parte, insa, trebuie sa avem in vedere faptul ca
dimensiunile acestor diagrame nu reflecta realitatea in ceea ce priveste continutul
celor trei clase. Ci dimpotriva: clasa Animal contine cele mai putine elemente, la care
se adauga alte cateva elemente in clasa Caine, care sunt uterior completate cu alte
cateva in clasa CaineAzor. (Termenul ”elemente” din ultima afirmatie poate ca nu
este cel mai bine ales, caci poate duce cu gandul la elemente ale multimii. Nu este
vorba de asa ceva, ci de elemente descriptive ale respectivei clase de obiecte. Iar
aceasta proportionalitate inversa intre numarul de obiecte ale unei clase si numarul
de elemente necesare descrierii ei nu este greu de inteles daca ne gandim la cum
stau lucrurile in realitate: cu cat dorim sa descriem o clasa mai restransa de obiecte,
cu atat avem nevoie de mai multe cuvinte.)
26
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
3.2. Exercitii
Animal
∟Caine
∟Pisica
Bibliografie
27
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
Lucrarea nr. 6
Polimorfism
1. Scopul lucrarii
2. Notiuni teoretice
28
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
+--------------------------------------------------------------------------------------------------+
|----------------------------------------------------------------------------------------------------|
| |
| +----------------------------+ |
| | Incarca | |
| +----------------------------+ |
| +----------------------------+ |
| | Mareste contrast | |
| +----------------------------+ |
| +----------------------------+ |
| | Micsoreaza contrast | |
| +----------------------------+ |
| |
+--------------------------------------------------------------------------------------------------+
Prin urmare, aplicatia va permite doar incarcarea unei imagini de pe disc si apoi
marirea sau micsorarea contrastului ei.
Exista, insa, mai multe tipuri de imagini, ca: imagini binare, imagini in nuante
de gri, imagini color, etc. Ceea ce inseamna ca fiecare pixel din imagine poate sa fie
fie o valoare binara, fie o valoare scalara, fie o valoare vectoriala, etc. Asta
inseamna ca in functie de tipul de imagine atat incarcarea si afisarea imaginii, cat si
manipularea contrastului ei pot presupune operatii foarte diferite.
clasa Imagine:
- Incarca(fisier)
- Afiseaza()
- MaresteContrast()
- MicsoreazaContrast.
Apoi putem introduce pe rand suport pentru diverse tipuri de imagini. Partea
interesanta consta in faptul ca nu va fi nevoie sa modificam programul deja scris.
Daca am proiectat programul astfel incat sa opereze corect cu obiecte de tip
Imagine, el va sti sa opereze bine si cu obiecte de tip ImagineColor, de exemplu.
Trebuie doar sa definesc clasa ImagineColor care sa mosteneasca clasa Imagine si
sa ii redefineasca cele patru metode publice.astfel incat noile metode sa opereze
corect cu imagini color.
29
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
class Imagine {
...
public:
virtual void Afiseaza();
};
...
class ImagineColor : public Imagine {
public:
void Afiseaza();
};
...
Imagine *pimg;
ImagineColor imgColor;
pimg = &imgColor;
p->Afiseaza(); // ← va apela metoda redefinita in clasa ImagineColor
3. Desfasurarea lucrarii
3.1. Exemplu
#include <stdio.h>
30
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
#include <conio.h>
class FormaGeometrica {
public:
int Arie();
};
int FormaGeometrica::Arie()
{
return 0;
}
return 0;
}
Cerc::Cerc(int r)
{
this->r = r;
}
int Cerc::Arie()
{
return 3.14*r*r;
}
int main(void)
{
FormaGeometrica *pf;
Dreptunghi d(20, 50);
Cerc c(30);
int arie;
pf = &d;
arie = pf->Arie();
printf(“%d\n”, arie); // → 0 !!!
getch();
pf = &c;
arie = pf->Arie();
printf(“%d\n”, arie); // → 0 !!!
getch();
return 0;
}
class FormaGeometrica {
public:
virtual int Arie();
};
32
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
3.2. Exercitii
(1) Sa se implementeze programul dat ca exemplu, atat fara “virtual”, cat si cu.
(2) Sa se scrie o functie generica ce calculeaza aria unei forme geometrice primite
ca parametru, ii citeste tipul si afiseaza aceste informatii pe ecran. Apoi sa se
realizeze un program de test care sa verifice aceasta functie trimitandu-i drept
parametri obiecte de diverse forme geometrice.
Idee:
void AfiseazaArie(FormaGeometrica *pf)
{
printf(“Tip obiect: %s. Arie: %d.\n”, pf->Tip(), pf->Arie());
}
Bibliografie
33
Florin Bîrleanu – Programare orientată pe obiecte pentru începători http://igotopia.ro
https://www.facebook.com/florinmarianb
sau pe email la
florin@igotopia.ro
34