Sunteți pe pagina 1din 6

Avantaje

n posibilitatea reutilizării codului


Reutilizarea codului. n obţinerea extensiei unei clase fară a fi
Moştenirea Claselor necesară o recompilare a clasei iniţiale;
n utilizarea polimorfismului în timpul executiei

Mihai Gabroveanu programului prin folosirea funcţiilor virtuale

Moştenirea Claselor 3

Ce este moştenirea? Reprezentare UML


ClasaDeBaza
n Mecanismul prin care o clasă preia structura (datele
membre) şi comportamentul (metodele) unei alte
clase la care adaugă elemente specifice.
Relaţia de
n Stabileste o relatie de tipul "este un/este o" (is-a) moştenire

n Clasă de baza = clasa de la care se preia structura ClasaDerivata


şi comportamentul
n Clasa derivată = clasa care preia structura şi
comportamentul

Moştenirea Claselor 2 Moştenirea Claselor 4


Exemplu Sintaxa definirii unei clase derivate
Produs
#nume:char [100]
#pret:float
n Sintaxa definirii unei clase derivate este următoarea:
+Produs(nume:char *,pret:float)
+getNume():char * class IdClasaDerivata: modif_acces1 IdClasaB1, …, modif_accesN IdClasaBn{
+getPret():float
//date si metode specifice clasei derivate
+afisare():void
};
unde:
n IdClasaDerivata este numele clasei derivate
n IdClasaB1, …, dClasaBn sunt clasele de bază de la care se moştenesc datele
ProdusElectronic ProdusAlimentar
şi metodele
#garantie:int #valabilitate:int
#consum:float n modif_acces1, …, modif_accesN sunt modificatori de acces: public, protected,
+ProdusAlimentar(nume:char *,pret:float,valabilitate:int)
+ProdusElectronic(nume:char *,pret:float,garantie:int,consum:float)
+getValabilitate():int private
+getGarantie():int +afisare():void
+getConsum():float
+afisare():void

Moştenirea Claselor 5 Moştenirea Claselor 7

Ce se moşteneşte? Accesul asupra membrilor moşteniţi

n În principiu, fiecare dată sau funcţie membru a clasei Protectia în clasa de bază Modificator de acces utilizat Drept de acces în clasa
de bază se moşteneşte în clasa derivată: în lista claselor de bază derivată
public public public
¨ diferă doar protecţia acestora private public inaccesibil
n Există şi excepţii: protected public protected

¨ Constructoriişi destructorii public private private


private private inaccesibil
¨ Supraîncărcarea operatorului =
protected private private
Aceştia nu se moştenesc, fiind metode specifice clasei

Moştenirea Claselor 6 Moştenirea Claselor 8


Exemplu Utilizarea datelor şi metodelor moştenite
Clasa derivată
derivata Clasa de bază
baza

void Produs::afisare(){ void main(){


class Produs{ class ProdusAlimentar: public Produs{ cout<<"Nume:"<<nume<<endl; ProdusAlimentar pa("Iaurt",15,30);
protected: protected: cout<<"Pret:"<<pret<<endl; pa.afisare();
char nume[100]; int valabilitate; } pa.Produs::afisare() ;
float pret; public: modificator acces
}
public: ProdusAlimentar(char *nume,
Produs(char *nume, float pret); float pret, int valabilitate); void ProdusAlimentar::afisare(){
char* getNume(); int getValabilitate();
Output
Produs::afisare(); Nume:Iaurt
float getPret(); void afisare(); cout<<"Valabilitate:"<<valabilitate;
void afisare(); }; Pret:15
cout<<endl; Valabilitate:30
}; }
Nume:Iaurt
Pret:15

Moştenirea Claselor 9 Moştenirea Claselor 11

Exemplu Tipuri de Moştenire


Clasa derivata Clasa de baza

class ProdusElectronic: private Produs{ int main(){


n Moştenire simplă – clasa derivată preia
protected:
int garantie;
ProdusAlimentar pa("Iaurt",15,30);
pa.afisare();
caracteristicile şi metodele unei singure clase
modificator acces
float consum;
public:
cout<<"Pretul p.a"<<pa.getPret();
ProdusElectronic pe("LCD",1000,24,12); de bază
ProdusElectronic(char *nume, float pe.afisare();
pret, int garantie, float consum); cout<<"Pretul p. e." <<pe.getPret(); n Moştenire multiplă - clasa derivată preia
int getGarantie();
float getConsum();
void afisare();
} caracteristicile şi metodele de la mai multe
inaccesibila
};
clase de bază

Moştenirea Claselor 10 Moştenirea Claselor 12


Moştenire Multiplă. Exemplu Apelul constructorilor claselor de bază
Imprimanta Scaner
n Explicit – Lista de initializare
#rezolutie:int #rezolutie:int
class D: public B1, …, public Bn{
Apelul explicit
+Imprimanta(rezolutie:int)
+Scaner(rezolutie:int) D(lista de parametri);
+~Imprimanta() +~Scaner() };
+print(text:char *):void +scan():void
D::D(lista de parametri):B1(sub_lista_param1), . . ., Bn(sub_lista_param1){
instructiuni
}

n Implicit – dacă constructorul clasei derivate nu apelează


MultiFunctionala
explicit constructorul uneia din clasele de bază atunci
+MultiFunctionala(rezI:int,rezS:int)
compilatorul va apela automat constructorul implicit al acelei
clase de bază
+~MultiFunctionala()

Moştenirea Claselor 13 Moştenirea Claselor 15

Constructori în procesul de moştenire Destructori în procesul de moştenire

n Dacă o clasă D este derivată din clase (B1, …, Bn) n La distrugerea unui obiect al clasei derivate
atunci constructorul clasei D va avea suficienţi
parametri pentru a iniţializa datele membru ale
compilatorul va executa mai întâi destructorul
claselor B1,…, Bn. clasei derivate şi apoi destructori claselor de
n La crearea unui obiect al clasei D se vor apela mai bază în ordinea inversă apelului constructorilor
întâi constructorii claselor B1, … ,Bn, în ordinea
specificată în lista de moştenire, pentru a se iniţializa
datele membre ale claselor de bază şi apoi se vor
executa intrucţiunile constructorului clasei D.

Moştenirea Claselor 14 Moştenirea Claselor 16


Exemplu Constructorul de copiere în procesul de moştenire

class Imprimanta{ class Scaner{


protected: protected: n Dacă clasa derivată nu are definit un constructor de
int rezolutie; int rezolutie; copiere atunci compilatorul generează unul automat care va
public: public:
Imprimanta(int rezolutie=600){ Scaner(int rezolutie=1200){ realiza copierea datelor membre moştenite apelând la
this->rezolutie = rezolutie;
cout<<"Apel Constr.
this->rezolutie = rezolutie;
cout<<"Apel Constr. Scaner\n";
constructorii de copiere ai claselor de bază (definiţi de
Imprimanta\n"; } utilizator sau generaţi de compilator), iar datele specifice
} ~Scaner(){
~Imprimanta(){ cout<<"Apel Destr. Scaner\n";
clasei derivate se vor copia bit cu bit.
cout<<"Apel Destr.
Imprimanta\n";
}
void scan(char *numeFisier){
n Dacă clasa derivată are definit un constructor de copiere
} cout<<"Scanez..."<<endl; atunci acesta se va realiza copierea tuturor datelor membre
void print(char *text){ cout<<"Salvez ";
cout<<"Print "<<text<<"\n"; cout<<numeFisier<<endl; (moştenite sau proprii) - apelând eventual la constructorii
} } claselor de bază
}; };

Moştenirea Claselor 17 Moştenirea Claselor 19

Exemplu Supraîncărcarea operatorului de atribuire


class MultiFunctionala: public Imprimanta, public OUTPUT
Scaner{
public: Apel Constr. Imprimanta
n Dacă clasa derivată nu are supraîncărcat operatorul
MultiFunctionala(int rezI, int rezS):
Imprimanta(rezI), Scaner(rezS){
Apel Constr. Scaner
Apel Constr. MultiFunctionala
de atribuire atunci compilatorul va realiza copierea
}
cout<<"Apel Constr. MultiFunctionala\n"; Print hello
Scanez...
datelor membre moştenite apelând la
~MultiFunctionala(){
cout<<"Apel Destr. MultiFunctionala\n";
Salvez test.pdf
Apel Destr. MultiFunctionala
supraîncărcările operatorului de atribuire definte în
} Apel Destr. Scaner clasele de bază (dacă există), iar datele membre
}; Apel Destr. Imprimanta
void main(){ specifice vor fii copiate bit cu bit
MultiFunctionala m(300,600);
m.print("hello");
m.scan("test.pdf");
n Dacă clasa derivată are supraîncărcat operatorul
}
Se afişează la distrugerea de atribuire atunci acesta va realiza copierea tuturor
obiectului m
datelor membre.

Moştenirea Claselor 18 Moştenirea Claselor 20


Exemplu Exemplu (cont.)
class Persoana{ int main(){ Apel constr. Persoana
protected: Persoana::~Persoana(){ Student s1("Mihai",19, "Informatica"); Apel constr. Student
char *nume; delete []nume; s1.afisare(); Nume:Mihai
int varsta; cout<<"Apel destructor Persoana\n"; Student s2=s1; Varsta:19
public: } s2.afisare(); Fac:Informatica
/** constructor cu parametri*/ Student s3("Maria",19, "Informatica"); Apel constr. Persoana
Persoana(char *nume, int varsta=0); s1 = s3; Apel Constr. de copiere Student
s1.afisare(); Nume:Mihai
/** Constructor de copiere*/ void Persoana::afisare(){
cout<<"Sfarsit program"<<endl; Varsta:19
Persoana(const Persoana &p); cout<<"Nume:" << nume <<endl; } Fac:Informatica
~Persoana(); cout<<"Varsta:" << varsta << endl; Apel constr. Persoana
void afisare(); } Apel constr. Student
Persoana& operator = (Persoana &p); Apel atribuire Student
}; Persoana& Persoana::operator = (Persoana &p){ Apel atribuire Persoana
Persoana::Persoana(char *nume, int varsta){ cout<<"Apel atribuire Persoana\n"; Nume:Maria
this -> nume = new char[strlen(nume)+1]; if (this != &p){ Apel supraîncărcării Varsta:19
strcpy(this -> nume, nume); delete []nume; operatorului de atribuire Fac:Informatica
this -> varsta = varsta; nume = new char[strlen(p.nume)+1]; Sfarsit program
Apel destructor Student
cout<<"Apel constr. Persoana\n"; strcpy(nume, p.nume);
Apel destructor Persoana
} varsta = p.varsta; Apel destructor Student
Persoana::Persoana(const Persoana &p){ } Apel destructor Persoana
nume = new char[strlen(p.nume)+1]; return *this; Apel destructor Student
strcpy(nume, p.nume); } Apel destructor Persoana
varsta = p.varsta;
cout<<"Apel Constr. de copiere Persoana\n";
}

Moştenirea Claselor 21 Moştenirea Claselor 23

Exemplu (cont.) Temă


class Student: public Persoana { Student::~Student(){
protected: delete []facultate;
char *facultate;
public:
Student(char *nume, int varsta, char *
}
cout<<"Apel destructor Student\n";

void Student::afisare(){
n Implementaţi clasa Angajat ce derivă din clasa
facultate);
Student(const Student &s);
~Student(); }
Persoana::afisare();
cout<<"Fac:"<<facultate<<endl; Persoana.
void afisare();

};
Student& operator = (Student &p); Student& Student::operator = (Student &s){
cout<<"Apel atribuire Student\n";
n Implementaţi o ierarhie de clase ce
Student::Student(char *nume, int varsta, char * if (this != &s){
facultate):Persoana(nume, varsta){
this -> facultate = new
Persoana::operator=(s);
delete []facultate;
reprezinta diferite figuri geometrice din plan.
char[strlen(facultate)+1]; facultate = new
strcpy(this -> facultate, facultate);
cout<<"Apel constr. Student\n";
char[strlen(s.facultate)+1];
strcpy(facultate, s.facultate); n Implementati ierarhia de clase Telefon,
} }
Student::Student(const Student &s):
Persoana(s.nume, s.varsta){ }
return *this; Apelul metodei moştenite
din clasa Persoana
TelefonFix, TelefonMobil.
facultate = new char[strlen(s.facultate)+1];
strcpy(facultate, s.facultate);
cout<<"Apel Constr. de copiere Student\n";
}

Moştenirea Claselor 22 Moştenirea Claselor 24

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