Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C....

24
Programare Orientată pe Obiecte Prof. Sanda Popescu

Transcript of Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C....

Page 1: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Programare Orientată pe Obiecte

Prof. Sanda Popescu

Page 2: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Scurtă istorie a limbajului C++

C++ a fost inventat de Bjarne Stroustrup în 1979 la Bell Laboratories în Murray Hill, New Jersey. Iniţial a fost numit C cu Clase, dar apoi în 1983 numele i-a fost schimbat în C++.

C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a suporta programarea obiect-orientată. C++ este versiunea obiect-orientată a limbajului C.

Invenţia C++ a fost necesară deoarece programele deveniseră mari şi complexe, şi chiar un limbaj excelent ca C, nu putea face faţă. În C, dacă un program depăşeşte 25000 – 100000 de linii, devine mult prea complex ca să-l înţelegi în totalitate.

C++ îşi propune să spargă această barieră, să permită programatorului să înţeleagă şi să administreze programe mari şi complexe.

Page 3: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Programarea Obiect-Orientată

Programarea Obiect-Orientată (POO sau OOP, de la Object-Oriented Programming) este o puternică metodologie de programare.

Anii 1960 au dat naştere programării structurate, metodă ce stă la baza limbajelor C sau Pascal. Programarea structurată îţi permitea să creezi, destul de uşor, programe de complexitate moderată. Chiar dacă este un concept puternic, limbajele structurate îşi ating limita atunci când un proiect devine mult prea mare.

Programarea obiect-orientată a preluat cele mai bune idei ale programării structurate şi le-a combinat cu noi concepte. Rezultatul a fost un nou stil de programare.

Principiul de bază al POO este că datele controlează accesul la cod. Într-un limbaj POO, programatorul defineşte datele şi operaţiile ce pot fi aplicate datelor. Toate limbajele OOP au trei trăsături în comun: încapsularea, polimorfismul şi moştenirea.

Page 4: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Avantajele OOP

• Preluarea soft-ului existent şi dezvoltarea altuia nou, prin adăugarea de date şi metode noi, fără a fi necesară cunoaşterea amănuntelor de realizarea soft-ului preluat

• Abordarea unitară a diverselor structuri, indiferent de forma lor concretă. În acest fel se pot trata unitar ferestrele, meniurile, datele de intrare, etc

Page 5: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Atenţie!

• Nu se va utiliza metoda POO în cazul aplicaţiilor simple, decât dacă dorim să explicăm, din punct de vedere didactic, mecanismul de funcţionare

• Soft-ul realizat prin POO necesită resurse de sistem performante (memorie, capacitate hard-disk, etc), datorită numărului mare de date şi metode care sunt definite în cadrul unui proiect dezvoltat prin POO.

• Uneori mecanismul de selecţie a metodelor poate fi greoi de utilizat

Page 6: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Concepte fundamentale

POO îmbină trei concepte fundamentale:

1. Încapsularea

2. Moştenirea

3. Polimorfismul

Page 7: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Încapsularea

Încapsularea este mecanismul ce leagă la un loc codul şi datele pe care le manipulează, şi le protejează de interferenţele şi abuzurile din afară (adică acel cod de program care nu este legat de datele respective).

Cu alte cuvinte, încapsularea este proprietatea ce permite ca o unică structură (obiectul) să conţină atât date cât şi metode (funcţii). În C++ încapsularea este obţinută prin structura numită clasă.

Într-un obiect atât datele (variabilele) cât şi codul (un set de instrucţiuni) pot fi private sau publice. Codul şi datele private sunt accesibile numai în obiectul curent, adică doar anumite părţi ale obiectului pot accesa acel cod şi acele date. Asta înseamnă că părţi ale programului ce nu fac parte din obiect, nu pot accesa codul şi datele private ale obiectului. În schimb, codul şi datele publice sunt disponibile oricărei părţi din program, pot fi accesate de oriunde.

În OOP, un obiect este practic o variabilă; de fapt, de fiecare dată când definim un nou tip de obiect, definim un nou tip de dată, şi fiecare instanţă a acestui tip este o variabilă compusă.

Page 8: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Moştenirea

Moştenirea este procesul prin care un obiect dobândeşte proprietăţile unui alt obiect. Acest lucru aduce în discuţie conceptul de clasificare sau ierarhizare. De exemplu: mărul face parte din clasa fructe, care, la rândul ei, face parte dintr-o clasă mai mare numită mâncare. Fără conceptul de clasificare, un obiect trebuie să-şi definească explicit toate caracteristicile. Atunci când se foloseşte moştenirea, obiectul trebuie doar să definească acele calităţi care-l fac unic, adică doar acele caracteristici particulare obiectului respectiv. Moştenirea este un aspect important al POO.

În C++ moştenirea este proprietatea ce permite ca dintr-o structură ce încorporează date şi metode, să obţinem noi structuri ce conţin noi date şi metode. Moştenirea se realizează prin derivarea claselor.

Page 9: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Polimorfismul

Polimorfismul poate fi caracterizat de fraza

"o singură interfaţă, multiple metode".

Polimorfismul este un atribut ce permite

utilizarea simultană a mai multor funcţii

(metode) care au un singur nume. În C++

polimorfismul este realizat prin

supraîncărcarea funcţiilor, dar mai ales

prin utilizarea funcţiilor virtuale.

Page 10: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Noţiunea de Clasă

O clasă defineşte un nou tip de dată ce specifică forma unui obiect. O clasă include atât date cât şi codul ce va opera asupra acelor date. Aşadar, o clasă leagă codul de date. Acest tip nou creat este folosit pentru a declara obiecte de tipul clasei. Obiectele sunt instanţe ale clasei. O clasă este o abstractizare logică, iar un obiect are o existenţă fizică. Clasa este tipul de dată, iar obiectul este variabila.

Funcţiile şi variabilele ce constituie clasa se numesc membri ai clasei respective. Aşadar, o variabilă declarată într-o clasă se numeşte variabilă membră, şi o funcţie declarată într-o clasă se numeşte funcţie membră.

Clasele sunt create cu cuvântul-cheie class. Declararea unei clase este asemănătoare cu declararea unei structuri.

Page 11: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Forma generală de declarare:

class nume-clasa { functii si date private specificator-de-acces: functii si date specificator-de-acces: functii si date // ... specificator-de-acces: functii si date } lista-obiecte;

Page 12: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Exemplu

Un principiu de bază al POO cere ca accesul la datele unui obiect să fie făcut exclusiv prin metodele sale .

Vom defini o clasă rational şi declarăm un obiect a, al acestei clase, pe care îl înzestrăm cu trei metode:

void nr(int x=0, int y=1) care permite introducerea valorilor p şi q ale obiectului (parametri impliciţi 0 şi 1);

int numarator() - returnează p; int numitor() - returnează q;

Page 13: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Programul C++

#include <iostream> #include <fstream> using namespace std; ifstream f("date.in"); ofstream g("date.out"); class rational { int p,q; public: void nr(int x=0, int y=1) { p=x; q=y; } int numarator() { return p; } int numitor() { return q; } float calcul(int p, int q) { return (float)p/q; } };

rational a; int x,y; int main() { f>>x>>y; a.nr(x,y); g<<a.numarator()<<' '<<a.numitor()<<'\n'; g<<a.calcul(a.numarator(), a.numitor()); return 0; }

Page 14: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Operatorul de rezoluţie ::

• Acest operator este indispensabil în studiul claselor

• Rolul său este de a permite accesul la variabilele globale ale programului

• Dacă sunt declarate două variabile, una globală şi una locală, având acelaşi nume, şi dorim ca în cadrul unui bloc să avem acces la variabila globală, utilizăm operatorul de rezoluţie care va precede variabila globală.

• Evident, am fi putut avea acces la variabila globală fără a utiliza operatorul ::, dacă nu am fi declarat o variabilă locală cu acelaşi nume.

Page 15: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Exemplu

#include <iostream> int i=1; int main() { int i=2; cout<<i<<‘ ’<<::i; // se afişează 2 1 return 0; } În cazul în care funcţiile sunt sunt scrise în cadrul clasei, ele

sunt privite de compilator ca funcţii inline. Concluzie: funcţia va fi descrisă în cadrul clasei numai dacă are codul extrem de scurt şi nu conţine instrucţiuni de ciclare. Altfel, clasa va conţine numai prototipul funcţiei.

Page 16: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Din exteriorul clasei, datele şi metodele ei nu sunt accesibile direct. Pentru rezolvare, se foloseşte operatorul de rezoluţie ::

#include <iostream> #include <fstream> using namespace std; ifstream f("date.in"); ofstream g("date.out"); class rational { int p, q; public: void nr(int, int); // prototip de funcţie int numarator(); // prototip de funcţie int numitor(); // prototip de funcţie float calcul(int, int); // prototip de funcţie }; rational a; int x,y; int i=1;

int main() { f>>x>>y; int i=2; a.nr(x,y); g<<a.numarator()<<' '<<a.numitor()<<'\n'; g<<a.calcul(a.numarator(), a.numitor())<<'\n'; g<<i<<‘ '<<::i<<'\n'; return 0; } void rational::nr(int x=0, int y=1) { p=x; q=y; } int rational::numarator() { return p; } int rational::numitor() { return q; } float rational::calcul(int p, int q) { return (float)p/q; }

Page 17: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Constructori

O metodă de a declara obiecte ale unei clase este prin intermediul unei metode speciale, ataşată clasei, numite constructor. Un astfel de constructor este numit constructor generat implicit.

Exemplu: # include <iostream.h> class intreg { public: int a; }; intreg g; int main() { intreg x, y, z; } Cu ajutorul constructorului generat implicit, s-au definit obiectele g,

x, y, z. O tentativă de a iniţializa la declarare un obiect (de exemplu intreg

t=34) este sancţionat cu mesajul error: conversion from `int' to non-scalar type ̀ intreg‘

Putem rezolva problema, înzestrând clasa cu o funcţie proprie constructor, care să respecte următoarele reguli:

- O metodă constructor are întotdeauna numele clasei din care face parte. Ea este apelată automat la declararea obiectelor

- Un constructor este o funcţie fără tip, dar în dreptul tipului nu se trece cuvântul cheie void

Exemplu # include <iostream.h> class intreg { public: int a; intreg() // nu are parametri formali { cout<<"da\n"; } }; intreg g; int main() { intreg x, y, z; } În urma execuţiei programului, se va afişa de 4 ori mesajul da,

pentru că se apelează constructorul pentru fiecare obiecte g, x, y, y declarat.

Page 18: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

În continuare, ataşăm clasei un constructor cu un parametru implicit, constructorul ataşat are rolul de a permite iniţializarea, la declarare, a datelor

# include <iostream.h> class intreg { public: int a; intreg (int v=12) // constructor cu parametru iniţializat { cout<<"da "<<v<<'\n'; a=v; } }; intreg g=1; int main() { intreg x=2, y=3.9, z(4), t(5.8),u; //cout<<x; încercarea de a afişa un obiect, generează eroare cout<<x.a<<' '<<y.a<<' '<<z.a<<' '<<t.a<<' '<<u.a; } Testaţi programul şi vedeţi ce afişează!

Sesizaţi cele trei moduri prin care se pot declara obiectele: 1. Utilizarea operatorului de atribuire: intreg g=1; 2. Prin utilizarea perechii de paranteze deschise: intreg t(5.8); 3. Fără a fi iniţializate explicit: intreg u;

Page 19: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Observaţii

• O clasă poate avea mai mulţi constructori, dar aveţi grijă ca aceştia să difere prin parametri (număr, tip), deoarece constructorii trebuie să poarte numele clasei

• De regulă, constructorii sunt definiţi în cadrul clasei, deoarece au puţine instrucţiuni, şi nu conţin instrucţiuni repetitive

• Un constructor nu poate avea un parametru formal de tipul clasei din care face parte

• Există o asemănare între declaraţia variabilelor şi declaraţia obiectelor. De exemplu:

int a, b, c; intreg x, y, z; Sunt corecte şi declaraţiile: int a(2), b(3), c(4); //ÎNCERCAŢI! intreg d=3, e=d; Concluzie: Clasele au caracteristicile tipurilor, obiectele au caracteristicile variabilelor

Page 20: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Destructori

• Operaţia de eliberare a memoriei alocate obiectelor este executată de o metodă specială, ataşată clasei, numită destructor.

• În cazul în care nu a fost definit un destructor, se generează implicit unul

• Numele destructorului coincide cu numele clasei, căreia îi aparţine, dar este precedat de caracterul ~

• Destructorul nu are parametri formali • O clasă are un singur destructor • Destructorul se apelează implicit când viaţa unui obiect

încetează, la sfârşitul blocului în care a fost declarat • Destructorul poate fi apelat explicit

Page 21: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

De obicei, obiectele se distrug în ordine inversă creării lor, programul următor afişează: creat 0 creat 2 creat 3 distrus 3 distrus 2 distrus 0

# include <iostream.h> class intreg { public: int a; intreg(int v=0) // construcor { cout<<"creat "<<v<<'\n'; a=v; } ~intreg () // destructor { cout<<"distrus"<<a<<'\n'; } }; intreg a; int main() { intreg x=2, y=3; }

TESTAŢI PROGRAMUL!!!

Page 22: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Rezolvaţi

Să se creeze clasa NumarNatural, ce cuprinde:

a. O dată membru x, întreg

b. Următoarele metode: i. Numărul de cifre zecimale ale lui x

ii. Reprezentarea în baza 2 a lui x

iii. Inversul (oglinditul) său

iv. Proprietatea de primalitate a lui x

c. constructori ce permit declaraţii ca: NumarNatural n, n(213)…

d. destructor

Scrieţi un program care citeşte un număr natural şi care afişează numărul de cifre ale numărului reprezentat în baza 2, verifică dacă este palindrom şi afişează mesajul E PRIM dacă numărul nu are divizori în afară de 1 şi el însuşi, sau mesajul NU E PRIM, în caz contrar.

Page 23: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Rezolvaţi

2. Să se creeze clasa NumarComplex, care permite lucrul cu numere complexe de forma z=a+bi, ce cuprinde:

a. Două date membru a, b de tip float

b. Constructori ce permit declaraţii ca: NumarComplex z, z(2) (ce reţine numărul z=2+0i), z(1.2, -7.5)

c. Destructor

d. Metode de adunare, scădere, înmulţire, împărţire a două numere complexe

Scrieţi un program care citeşte două numere complexe şi tipăreşte suma, diferenţa, produsul, câtul lor.

Page 24: Programare Orientată pe Obiecte - prof. Sanda Popescu · C++ conţine întreg limbajul C. Majoritatea completărilor făcute de Stroustrup limbajului C au fost concepute pentru a

Rezolvaţi

3. Să se creeze clasa NumarRational, care permite lucrul cu numere raţionale de forma x=p/q, ce cuprinde:

a. Două date membru p şi q de tip întreg

b. Constructori ce permit declaraţii ca: NumarRational a, a(2,5)

c. Destructor

d. Metode de adunare, înmulţire, împarţire a două numere raţionale

e. Metodă de simplificare a unui număr raţional cu cel mai mare divizor comun dintre p şi q

f. Metodă de amplificare a unui număr raţional cu un număr natural transmis prin parametru

Scrieţi un program care citeşte două numere raţionale şi tipăreşte suma, produsul, câtul acestora, precum şi verificarea unui număr raţional dacă este ireductibil, în caz contrar să se simplifice numărul ca să devină ireductibil. Să se implementeze algoritmul care aduce două fracţii la acelaşi numitor comun.