Programarea Orientată pe Obiecte – Clase și Obiecte
1. Obiectivele lecției:
- Să înțeleagă conceptul de programare orientată pe obiecte (POO).
- Să învețe definiția claselor și obiectelor.
- Să implementeze exemple practice care utilizează clase și obiecte.
2. Ce este Programarea Orientată pe Obiecte (POO)?
- Definiție:
Programarea orientată pe obiecte este un stil de programare care se concentrează pe utilizarea obiectelor – entități care combină date (atribute) și comportament (metode). - Principiile POO:
- Încapsulare: Gruparea datelor și metodelor care le operează într-o clasă.
- Moștenire: Posibilitatea de a crea noi clase bazate pe clase existente.
- Polimorfism: Capacitatea de a utiliza aceeași interfață pentru diferite tipuri de obiecte.
- Abstracție: Ascunderea detaliilor complexe ale implementării.
3. Clase și Obiecte
1. Clase
- Definiție:
- O clasă este un șablon care definește structura și comportamentul obiectelor. Ea descrie ce atribute și metode vor avea obiectele create pe baza sa.
- Structura unei clase:
class NumeClasa {
private:
// Atribute private
public:
// Constructori
// Metode publice
};
- Exemplu:
class Masina {
private:
string marca;
int vitezaMaxima;
public:
// Constructor
Masina(string m, int v) {
marca = m;
vitezaMaxima = v;
}
// Metodă pentru afișare
void afiseazaDetalii() {
cout << „Marca: ” << marca << „, Viteza maxima: ” << vitezaMaxima << ” km/h” << endl;
}
};
2. Obiecte
- Definiție:
- Un obiect este o instanță a unei clase. El reprezintă o entitate concretă care urmează structura și comportamentul definite de clasă.
- Crearea unui obiect:
Masina masina1(„Toyota”, 180); // Obiect de tip Masina
masina1.afiseazaDetalii();
4. Exemple practice
Exemplu 1: Crearea unei clase simple
- Definiția clasei:
class Student {
private:
string nume;
int varsta;
public:
// Constructor
Student(string n, int v) {
nume = n;
varsta = v;
}
// Metodă pentru afișare
void afiseazaDetalii() {
cout << „Nume: ” << nume << „, Varsta: ” << varsta << ” ani” << endl;
}
};
- Utilizarea obiectelor:
int main() {
Student s1(„Andrei”, 20);
Student s2(„Maria”, 22);
s1.afiseazaDetalii();
s2.afiseazaDetalii();
return 0;
}
Exemplu 2: Clase cu metode pentru operații
- Definiția clasei:
class Dreptunghi {
private:
int lungime;
int latime;
public:
// Constructor
Dreptunghi(int l, int L) {
lungime = l;
latime = L;
}
// Metode pentru calcul
int calculeazaAria() {
return lungime * latime;
}
int calculeazaPerimetrul() {
return 2 * (lungime + latime);
}
};
- Utilizarea obiectelor:
int main() {
Dreptunghi d(5, 10);
cout << „Aria: ” << d.calculeazaAria() << endl;
cout << „Perimetrul: ” << d.calculeazaPerimetrul() << endl;
return 0;
}
Exemplu 3: Încapsularea datelor
- Definiția clasei:
class ContBancar {
private:
string titular;
double sold;
public:
// Constructor
ContBancar(string t, double s) {
titular = t;
sold = s;
}
// Metode pentru operare
void depune(double suma) {
sold += suma;
}
void retrage(double suma) {
if (suma <= sold) {
sold -= suma;
} else {
cout << „Fonduri insuficiente!” << endl;
}
}
void afiseazaSold() {
cout << „Titular: ” << titular << „, Sold: ” << sold << ” lei” << endl;
}
};
- Utilizarea obiectelor:
int main() {
ContBancar cont(„Ioan Popescu”, 1000.0);
cont.afiseazaSold();
cont.depune(500);
cont.afiseazaSold();
cont.retrage(2000);
cont.retrage(100);
cont.afiseazaSold();
return 0;
}
5. Avantajele utilizării claselor și obiectelor
Avantaj | Descriere |
Modularitate | Codul este organizat în module independente. |
Reutilizare | Clasele pot fi utilizate în mai multe programe. |
Întreținere ușoară | Modificările în cod sunt izolate și ușor de gestionat. |
Abstracție | Ascunde detaliile implementării, punând accent pe utilizare. |
Moștenire și extensibilitate | Clasele pot fi extinse pentru a adăuga funcționalități noi. |
6. Activități practice pentru elevi
- Creați o clasă Carte cu atributele titlu, autor și numarPagini. Implementați metode pentru afișarea detaliilor și actualizarea numărului de pagini.
- Implementați o clasă Cerc care calculează aria și circumferința.
- Scrieți un program care folosește o clasă Elev pentru a gestiona numele, vârsta și media elevilor.
7. Scheme logice
- Crearea unui obiect:
- Start -> Declarare clasă -> Definire constructor -> Inițializare obiect -> Utilizare metode -> Stop.
- Flux de utilizare a unei clase:
- Definiție clasă -> Declarare metode -> Creare obiect -> Apelare metode.
8. Concluzie
- Clasele și obiectele sunt fundamentul programării orientate pe obiecte.
- Încapsularea datelor și metodelor permite organizarea clară a codului și reducerea erorilor.
- Practica este esențială pentru a înțelege și a aplica eficient conceptul de clase și obiecte.
Programarea Orientată pe Obiecte – Principii și Abstractizarea
1. Obiectivele lecției:
- Să înțeleagă cele patru principii fundamentale ale programării orientate pe obiecte (POO).
- Să exploreze conceptul de abstractizare și aplicarea acestuia în proiectarea software.
- Să implementeze exemple practice pentru a înțelege abstractizarea.
2. Principiile fundamentale ale POO
1. Încapsularea
- Definiție:
Gruparea datelor (atribute) și a funcțiilor care operează asupra acestor date (metode) într-o singură entitate numită clasă.
Atributele sunt protejate de accesul direct folosind modificatori de acces (private, protected, public). - Avantaje:
- Protecția datelor.
- Control asupra modului în care datele sunt accesate sau modificate.
- Exemplu:
class ContBancar {
private:
double sold;
public:
void depune(double suma) {
sold += suma;
}
double obtineSold() {
return sold;
}
};
2. Abstractizarea
- Definiție:
Procesul de a ascunde detaliile implementării și de a expune doar funcționalitatea esențială utilizatorului. - Exemplu real:
O mașină – utilizatorul folosește pedala de accelerație pentru a crește viteza fără a înțelege cum funcționează motorul intern. - Avantaje:
- Simplifică complexitatea.
- Reduce dependența utilizatorului de implementare.
- Exemplu:
class Vehicul {
public:
virtual void porneste() = 0; // Metodă pur abstractă
};
class Masina : public Vehicul {
public:
void porneste() override {
cout << „Mașina a pornit.” << endl;
}
};
int main() {
Vehicul* v = new Masina();
v->porneste();
return 0;
}
3. Moștenirea
- Definiție:
Permite crearea unei noi clase (clasă derivată) bazată pe o clasă existentă (clasă de bază), moștenind atributele și metodele acesteia. - Avantaje:
- Reutilizarea codului.
- Crearea de ierarhii logice.
- Exemplu:
class Animal {
public:
void mananca() {
cout << „Animalul mănâncă.” << endl;
}
};
class Pisica : public Animal {
public:
void miauna() {
cout << „Pisica miaună.” << endl;
}
};
4. Polimorfismul
- Definiție:
Capacitatea de a utiliza aceeași interfață pentru diferite implementări. - Tipuri:
- Polimorfism static: Suprasarcina funcțiilor (funcții cu același nume, dar parametri diferiți).
- Polimorfism dinamic: Suprascrierea metodelor în clase derivate.
- Exemplu de polimorfism dinamic:
class Animal {
public:
virtual void sunet() {
cout << „Animalul face un sunet.” << endl;
}
};
class Caine : public Animal {
public:
void sunet() override {
cout << „Câinele latră.” << endl;
}
};
int main() {
Animal* a = new Caine();
a->sunet(); // Apelează metoda din clasa Caine
return 0;
}
3. Abstractizarea în detaliu
1. Clase abstracte
- Definiție:
O clasă care nu poate fi instanțiată direct și care conține metode pur abstracte (declarații fără implementare).
Metodele pur abstracte sunt definite folosind = 0. - Exemplu:
class Forma {
public:
virtual void desen() = 0; // Metodă pur abstractă
};
class Cerc : public Forma {
public:
void desen() override {
cout << „Desenez un cerc.” << endl;
}
};
int main() {
Forma* f = new Cerc();
f->desen();
return 0;
}
2. Interfețe (în alte limbaje, similare cu clase abstracte în C++)
- Definiție:
Reprezintă un contract care definește metodele pe care o clasă derivată trebuie să le implementeze. - Exemplu:
class Calcul {
public:
virtual int calculeaza(int a, int b) = 0;
};
class Adunare : public Calcul {
public:
int calculeaza(int a, int b) override {
return a + b;
}
};
int main() {
Calcul* c = new Adunare();
cout << „Rezultatul: ” << c->calculeaza(5, 3) << endl;
return 0;
}
4. Avantajele abstractizării
- Simplificare:
Codul este mai ușor de înțeles și utilizat. - Flexibilitate:
Permite schimbarea implementării fără a afecta utilizatorii. - Extensibilitate:
Ușurează adăugarea de noi funcționalități fără a modifica codul existent.
5. Exemple practice
Exemplu 1: Aplicație pentru forme geometrice
#include <iostream>
using namespace std;
class Forma {
public:
virtual double calculeazaAria() = 0; // Metodă pur abstractă
};
class Dreptunghi : public Forma {
private:
double lungime, latime;
public:
Dreptunghi(double l, double L) : lungime(l), latime(L) {}
double calculeazaAria() override {
return lungime * latime;
}
};
class Cerc : public Forma {
private:
double raza;
public:
Cerc(double r) : raza(r) {}
double calculeazaAria() override {
return 3.14 * raza * raza;
}
};
int main() {
Forma* dreptunghi = new Dreptunghi(5, 10);
Forma* cerc = new Cerc(7);
cout << „Aria dreptunghiului: ” << dreptunghi->calculeazaAria() << endl;
cout << „Aria cercului: ” << cerc->calculeazaAria() << endl;
delete dreptunghi;
delete cerc;
return 0;
}
Exemplu 2: Sistem de plăți
#include <iostream>
using namespace std;
class Plata {
public:
virtual void proceseazaPlata(double suma) = 0;
};
class PlataCard : public Plata {
public:
void proceseazaPlata(double suma) override {
cout << „Plata de ” << suma << ” lei a fost procesată prin card.” << endl;
}
};
class PlataCash : public Plata {
public:
void proceseazaPlata(double suma) override {
cout << „Plata de ” << suma << ” lei a fost procesată prin cash.” << endl;
}
};
int main() {
Plata* plata = new PlataCard();
plata->proceseazaPlata(150.5);
plata = new PlataCash();
plata->proceseazaPlata(200);
return 0;
}
6. Activități practice pentru elevi
- Creați o clasă abstractă Animal cu o metodă pur abstractă sunet. Implementați clasele Caine și Pisica.
- Realizați un program care modelează vehicule (clasă abstractă Vehicul cu metode pentru pornire și oprire).
- Scrieți un program care implementează un sistem de management al plăților utilizând abstractizarea.
7. Concluzie
- Abstractizarea este un concept esențial în programarea orientată pe obiecte care simplifică interacțiunea utilizatorului cu sistemul.
- Prin separarea detaliilor de implementare, codul devine mai ușor de întreținut și extins.
- Practica și utilizarea claselor abstracte și a polimorfismului ajută la construirea de aplicații robuste și scalabile.
Programarea Orientată pe Obiecte – Principii și Moștenirea
1. Obiectivele lecției:
- Să înțeleagă cele patru principii fundamentale ale programării orientate pe obiecte (POO).
- Să înțeleagă conceptul de moștenire și aplicarea sa în POO.
- Să implementeze exemple practice care utilizează moștenirea pentru reutilizarea codului și extinderea funcționalității.
2. Principiile fundamentale ale POO
1. Încapsularea
- Definiție:
Gruparea datelor (atribute) și a funcțiilor (metode) care operează asupra acestor date într-o clasă. Încapsularea ascunde detaliile implementării folosind modificatori de acces precum private, protected și public. - Exemplu:
class ContBancar {
private:
double sold;
public:
void depune(double suma) {
sold += suma;
}
double obtineSold() {
return sold;
}
};
2. Abstractizarea
- Definiție:
Procesul de a ascunde detaliile complexe și de a expune doar funcționalitățile relevante utilizatorului. Se realizează prin clase abstracte și interfețe. - Exemplu:
class Vehicul {
public:
virtual void porneste() = 0; // Metodă pur abstractă
};
class Masina : public Vehicul {
public:
void porneste() override {
cout << „Mașina a pornit.” << endl;
}
};
3. Moștenirea
- Definiție:
Moștenirea permite unei clase noi (clasă derivată) să preia atributele și metodele unei clase existente (clasă de bază), reducând astfel redundanța și încurajând reutilizarea codului. - Tipuri de moștenire:
- Public: Membrii publici și protejați ai clasei de bază devin publici și protejați în clasa derivată.
- Protected: Membrii publici și protejați ai clasei de bază devin protejați în clasa derivată.
- Private: Toți membrii devin private în clasa derivată.
- Sintaxă:
class ClasaDerivata : ModAcces ClasaDeBaza {
// Membri suplimentari
};
- Exemplu:
class Animal {
public:
void mananca() {
cout << „Animalul mănâncă.” << endl;
}
};
class Pisica : public Animal {
public:
void miauna() {
cout << „Pisica miaună.” << endl;
}
};
int main() {
Pisica p;
p.mananca();
p.miauna();
return 0;
}
4. Polimorfism
- Definiție:
Capacitatea de a utiliza aceeași interfață pentru diferite tipuri de obiecte, permițând clasele derivate să implementeze comportamente specifice. - Exemplu:
class Animal {
public:
virtual void sunet() {
cout << „Animalul face un sunet.” << endl;
}
};
class Caine : public Animal {
public:
void sunet() override {
cout << „Câinele latră.” << endl;
}
};
int main() {
Animal* a = new Caine();
a->sunet(); // Apelează metoda din clasa Caine
return 0;
}
3. Moștenirea în detaliu
1. Avantajele moștenirii
Avantaj | Descriere |
Reutilizarea codului | Permite utilizarea funcționalităților clasei de bază fără rescriere. |
Extensibilitate | Ușurează extinderea funcționalităților prin clase derivate. |
Claritate | Creează o ierarhie logică a claselor. |
2. Modificatori de acces și moștenirea
Modificator | Accesibil în clasa de bază | Accesibil în clasa derivată | Accesibil în afara clasei |
public | Da | Da | Da |
protected | Da | Da | Nu |
private | Da | Nu | Nu |
3. Exemple practice
Exemplu 1: Crearea unei ierarhii de clase
- Clasa de bază și clasa derivată:
class Vehicul {
public:
void porneste() {
cout << „Vehiculul pornește.” << endl;
}
};
class Masina : public Vehicul {
public:
void accelereaza() {
cout << „Mașina accelerează.” << endl;
}
};
int main() {
Masina m;
m.porneste();
m.accelereaza();
return 0;
}
Exemplu 2: Utilizarea constructorilor în moștenire
- Transmiterea datelor către clasa de bază:
class Persoana {
protected:
string nume;
public:
Persoana(string n) : nume(n) {}
};
class Student : public Persoana {
private:
int anStudiu;
public:
Student(string n, int an) : Persoana(n), anStudiu(an) {}
void afiseazaDetalii() {
cout << „Nume: ” << nume << „, An de studiu: ” << anStudiu << endl;
}
};
int main() {
Student s(„Andrei”, 2);
s.afiseazaDetalii();
return 0;
}
Exemplu 3: Polimorfism cu metode suprascrise
- Definirea metodelor virtuale:
class Forma {
public:
virtual void desen() {
cout << „Desenez o formă generică.” << endl;
}
};
class Dreptunghi : public Forma {
public:
void desen() override {
cout << „Desenez un dreptunghi.” << endl;
}
};
int main() {
Forma* f = new Dreptunghi();
f->desen(); // Apelează metoda din Dreptunghi
return 0;
}
4. Activități practice pentru elevi
- Creați o clasă de bază Animal cu metode pentru mananca() și doarme(). Extindeți clasele Pisica și Caine care adaugă metode specifice.
- Implementați o clasă abstractă Vehicul și derivatele Bicicleta și Motocicleta, fiecare cu o metodă descriere().
- Realizați un program care modelează o ierarhie pentru produse alimentare (Produs -> Fruct -> Mar).
5. Scheme logice
- Moștenirea simplă:
- Start -> Definire clasă de bază -> Definire clasă derivată -> Utilizare metode -> Stop.
- Constructori și moștenire:
- Start -> Constructor clasa derivată -> Apel constructor clasa de bază -> Inițializare -> Stop.
6. Concluzie
- Moștenirea este un principiu fundamental al POO care permite reutilizarea codului și extensibilitatea aplicațiilor.
- Este importantă utilizarea corectă a modificatorilor de acces pentru a proteja datele și pentru a controla vizibilitatea acestora.
- Moștenirea devine mai puternică atunci când este combinată cu polimorfismul, permițând implementări flexibile și scalabile.