Sunteți pe pagina 1din 6

Avantaje

n posibilitatea reutilizarii codului


Reutilizarea codului. n obinerea extensiei unei clase far a fi
Motenirea Claselor necesar o recompilare a clasei initiale;
n utilizarea polimorfismului n timpul executiei

Mihai Gabroveanu programului prin folosirea functiilor virtuale

Motenirea Claselor 3

Ce este motenirea? Reprezentare UML


ClasaDeBaza
n Mecanismul prin care o clas preia structura (datele
membru) i comportamentul (metodele) unei alte
clase la care adaug elemente specifice.
n n limbajul C++ este implementat prin conceptul de Relaia de
motenire motenire

n Stabileste o relatie de genul "este un/este o" (is-a)


ClasaDerivata
n Clas de baza = clasa de la care se preia structura
i comportamentul
n Clasa derivat = clasa care preia structura i
comportamentul

Motenirea Claselor 2 Motenirea Claselor 4


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

Motenirea Claselor 5 Motenirea Claselor 7

Ce se motenete? Accesul asupra membrilor motenii

n n principiu, fiecare dat sau funcie membru a clasei Protectia n clasa de baz Modificator de acces utilizat Drept de acces n clasa
de baz se motenete n clasa derivat: n lista claselor de baz derivat
public public public
difer doar protecia acestora private public inaccesibil
n Exist i excepii: protected public protected

Constructorii i destructorii public private private


private private inaccesibil
Suprancrcarea operatorului =
protected private private
Acetia nu se motenesc, fiind metode specifice clasei

Motenirea Claselor 6 Motenirea Claselor 8


Exemplu Utilizarea datelor i metodelor motenite
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

Motenirea Claselor 9 Motenirea Claselor 11

Exemplu Tipuri de Motenire


Clasa derivata Clasa de baza

class ProdusElectronic: private Produs{ int main(){


n Motenire 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 Motenire multipl - clasa derivat preia
int getGarantie();
float getConsum();
void afisare();
} caracteristicile i metodele de la mai multe
inaccesibila
};
clase de baz

Motenirea Claselor 10 Motenirea Claselor 12


Motenire Multipl. Exemplu Apelul constructorilor claselor de baz
Imprimanta Scaner
#rezolutie:int #rezolutie:int
n Explicit Lista de initializare
class D: public B1, , public Bn{
+Imprimanta(rezolutie:int)
+Scaner(rezolutie:int) Apelul explicit
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
+~MultiFunctionala()
clase de baz

Motenirea Claselor 13 Motenirea Claselor 15

Constructori n procesul de motenire Destructori n procesul de motenire

n Dac o clas D este derivata din clase (B1, , Bn) n La distrugerea unui obiect al clasei derivate
atunci constructorul clasei B va avea suficieni
parametri pentru a iniializa datele membru ale
compilatorul va executa mai nti 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
nti constructorii claselor B1, ,Bn, n ordinea
specificat n lista de motenire, pentru a se iniializa
datele membre ale claselor de baz i apoi se vor
executa intruciunile constructorului clasei D.

Motenirea Claselor 14 Motenirea Claselor 16


Exemplu Constructorul de copiere n procesul de motenire

class Imprimanta{ class Scaner{


protected: protected: n Dac clasa derivat nu are definit un constructor de
int rezolutie;
public:
int rezolutie;
public:
copiere atunci compilatorul genereaz unul automat care va
Imprimanta(int rezolutie=600){ Scaner(int rezolutie=1200){ realiza copierea datelor membre motenite apelnd la
this->rezolutie = rezolutie;
cout<<"Apel Constr.
this->rezolutie = rezolutie;
cout<<"Apel Constr. Scaner\n";
constructorii de copiere ai claselor de baz (definii de
Imprimanta\n"; } utilizator sau generai 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(){
n Dac clasa derivat are definit un constructor de copiere
} cout<<"Scanez\n"; atunci acesta se va realiza copierea tuturor datelor membre
void print(char *text){ }
cout<<"Print "<<text<<"\n"; };
(motenite sau proprii) - apelnd eventual la constructorii
} claselor de baz
};

Motenirea Claselor 17 Motenirea Claselor 19

Exemplu Suprancrcarea operatorului de atribuire


class MultiFunctionala: public Imprimanta, public OUTPUT
Scaner{
public: Apel Constr. Imprimanta
n Dac clasa derivat nu are suprancrcat 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 motenite apelnd la
~MultiFunctionala(){
cout<<"Apel Destr. MultiFunctionala\n";
Apel Destr. MultiFunctionala
Apel Destr. Scaner
suprancrcrile operatorului de atribuire definte n
} Apel Destr. Imprimanta clasele de baz (dac exist), iar datele membre
};
void main(){ specifice vor fii copiate bit cu bit
MultiFunctionala m(300,600);
m.print("hello");
m.scan();
n Dac clasa derivat are suprancrcat operatorul
}
Se afieaz la distrugerea de atribuire atunci acesta va realiza copierea tuturor
obiectului m
datelor membre.

Motenirea Claselor 18 Motenirea 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("Anca",19, "Informatica"); Apel constr. Persoana
Persoana(char *nume, int varsta=0); s1 = s3; Apel Constr. de copiere Student
/** Constructor de copiere*/ void Persoana::afisare(){ s1.afisare(); Nume:Mihai
Persoana(const Persoana &p); cout<<"Nume:" << nume <<endl; getch(); Varsta:19
~Persoana(); cout<<"Varsta:" << varsta << endl; } Fac:Informatica
void afisare(); } Apel constr. Persoana
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:Anca
this -> nume = new char[strlen(nume)+1]; if (this != &p){ Varsta:19
strcpy(this -> nume, nume); delete []nume; Fac:Informatica
this -> varsta = varsta; nume = new char[strlen(p.nume)+1]; 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";
}

Motenirea Claselor 21 Motenirea 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 Implementai 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 Implementai 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 motenite
din clasa Persoana
TelefonFix, TelefonMobil.
facultate = new char[strlen(s.facultate)+1];
strcpy(facultate, s.facultate);
cout<<"Apel Constr. de copiere Student\n";
}

Motenirea Claselor 22 Motenirea Claselor 24