Mihaela M. Oprea, Programare orientatã pe obiecte [628312]

 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -MODULUL 3
Mostenire
Obiective
• Definirea notiunilor de clasã de bazã, clasã derivatã,
ierarhie de clase, mostenire
• Însusirea modalitãtii de creare de noi clase pornind de la
clase existente
• Întelegerea rolului membrilor protejati ai unei clase
• Însusirea mecanismului de redefinire a membrilor unei clase
într-o clasã derivatã
Termeni cheie
Derivare Mostenire
Clasã de bazã Clasã derivatã
Ierarhie de clase Membrii protejati
Redefinirea functiilor Supraîncãrcarea fun ctiilor

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -78
LECTIA 5
Relatia de mostenire. Clase de bazã si clase derivate
Mostenirea reprezintã o formã de implementare a reutilizãrii
codului. Ea apare în urma creãrii de noi clase prin operatia de
derivare.
Derivarea reprezintã definirea unei noi clase prin extinderea
uneia sau a mai multor clase existente. Noua clasã se numeste
clasã derivatã , iar clasele existente din care a fost derivatã se
numesc clase de bazã . În cazul în care existã o singurã clasã de
bazã, mostenirea se numeste mostenire singularã . Limbajul
C++ acceptã existenta mai multor clase de bazã. Despre aceastã
facilitate, numitã mostenire multiplã , vom discuta în modulul 5.
O clasã derivatã mosteneste toti membrii tuturor claselor sale de
bazã. Adicã, clasa derivatã contine toate variabilele membru
continute în clasele de bazã si suportã toate operatiile furnizate
de clasele de bazã.
Definitie : Mostenirea este mecanismul care permite unei clase
A sã mosteneascã proprietãtile unei clase B. Spunem cã “A
mosteneste clasa B”. Obiectele clasei A au astfel acces la
atributele si metodele clasei B fãrã necesitatea de a le redefini.
Definitie : Dacã clasa A mosteneste clasa B atunci clasa B se
numeste clasã de bazã sau superclasã sau clasã pãrinte , iar
clasa A se numeste clasã derivatã sau subclasã sau clasã copil .
O clasã derivatã poate fi la rândul ei clasã de bazã pentru noi
clase. Astfel se poate genera o ierarhie de clase (graf de
mostenire ).
Sintaxa declarãrii unei clase derivate dintr-o clasã de bazã :
class <clasa_derivatã > : public <clasa_de_bazã >
{ // membrii clasei derivate
};

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -79
Mostenirea sau relatia de derivare este indicatã în antetul clasei
derivate prin cuvântul cheie public prefixat de caracterul “:” si
urmat de numele clasei de bazã.
În cadrul relatiei de mostenire poate apare în clasa de bazã o
sectiune protejatã, marcatã prin cuvântul cheie protected , care
permite accesul claselor derivate din ea la datele si functiile
membru din sectiunea respectivã.
AObservatii
• O clasã derivatã nu poate accesa direct membrii privati ai
clasei sale de bazã. Dacã s-ar permite asa ceva s-ar încãlca
unul din principiile fundamentale ale POO (încapsularea).
• O clasã derivatã poate accesa membrii privati doar prin
intermediul functiilor publice si protejate ale clasei de bazã.
• O clasã derivatã poate accesa membrii publici si protejati ai
clasei de bazã.
• Relatia de mostenire este tranzitivã.
• Functiile friend nu se mostenesc.
Programul P3.1 prezintã un exemplu de definire a douã clase
Persoana si Student: [anonimizat], clasa Student
fiind derivatã din clasa de bazã Persoana .
// fisierul sursa P3_1.cpp
#include <iostream.h>
#include <string.h>
#define max 20
// clasa de baza Persoana
class Persoana {
char nume[max], pren[max];
char strada[max];
int nr;
public:
Persoana(char*, char*, char*, int);
void afisarePersoana();
};
Programul P3.1 (1/2)

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -80
Persoana::Persoana(char* N, char* P, char* S,int NR)
{
strcpy(nume, N);
strcpy(pren, P);
strcpy(strada, S);
nr=NR;
}
void Persoana::afisarePersoana()
{
cout<<"\n Date personale:\n Nume:"<<nume<<"\t Pren:"<<pren;
cout<<"\t Str."<<strada<<"Nr. "<<nr;
}
// clasa derivata Student
class Student:public Persoana {
char spec[max]; // specializarea
int grupa;
int an;
public:
Student(char* , char*, char*, int, char*, int, int);
void afisareStudent();
};
Student::Student(char* N, char* P,
char* S, int Nr, char* SP, int G, int A)
:Persoana(N, P, S, Nr)
{
strcpy(spec, SP);
grupa=G;
an=A;
}
void Student::afisareStudent()
{
cout<<"\n\t Afisare date student:";
afisarePersoana();
cout<<"\t Spec:"<<spec<<"\t gr."<<grupa<<"\t an "<<an;
}
void main()
{
Student S1=Student("Irimia", "Alina", "Bd. Independentei",
12, "AII", 1810, 1);
S1.afisareStudent();
}
Programul P3.2 (2/2)
Clasa Student mosteneste de la clasa Persoana toate datele
membru ( nume , pren, strada , nr) si functiile membru
(afisarePesoana ()) si în plus, contine date membru suplimentare
(spec, grupa , an) si functii membru specifice ( afisareStudent ()).

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -81
În corpul functiei afisareStudent () este apelatã functia
afisarePersoana () (functie membru mostenitã de la clasa
Persoana ) care afiseazã datele personale ale unui obiect de tip
Student . În continuare, functia afisareStudent () afiseazã datele
specifice obiectului de tip Student . O observatie importantã se
referã la apelul constructorului clasei de bazã de cãtre
constructorul clasei derivate, prin transmiterea parametrilor
specifici constructorului clasei de bazã.
Relatia de mostenire genereazã o ierarhie de clase, o clasã de
bazã fiind într-o relatie ierarhicã directã sau indirectã cu clasele
ei derivate. În figura 3.1 este prezentatã o ierarhie de clase
pornind de la clasa de bazã Forma2D din care sunt derivate
clasele Triunghi , Dreptunghi , Cerc , iar din clasa Dreptunghi
este derivatã clasa Patrat . În aces caz, clasa Forma2D se aflã
într-o relatie ierarhicã indirectã cu clasa Patrat .
Fig. 3.1 Exemplu de ierarhie de clase.Forma2D
PatratCerc Dreptunghi Triunghi

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -82
Apelul constructorilor si destructorilor
În cazul în care o clasã de bazã si una derivatã contin
constructori si destructori, constructorii sunt executati în ordinea
derivãrii, iar destructorii în ordine inversã. Astfel, se executã
mai întâi constructorul clasei de bazã, apoi constructorul clasei
derivate. La sfârsit se apeleazã mai întâi destructorul clasei
derivate si apoi destructorul clasei de bazã.
Rularea programului P3.2 va afisa mesaje corespunzãtoare
apelurilor de constructori, respectiv destructori ilustrând
modalitatea lor de apel. Programul P3.2 creeazã si distruge
obiectul ob1 al clasei DERIVATA .
// fisierul sursa P3_2.cpp
#include <iostream.h>
class BAZA {
public:
BAZA()
{
cout<<"\n Constructorul clasei de baza.";
}
~BAZA()
{
cout<<"\n Destructorul clasei de baza.";
}
};
class DERIVATA:public BAZA {
public:
DERIVATA()
{
cout<<"\n Constructorul clasei derivate.";
}
~DERIVATA()
{
cout<<"\n Destructorul clasei derivate.";
}
};
void main()
{
DERIVATA ob1;
}
Programul P3.2

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -83
Sintaxa generalã pentru transmiterea de argumente din clasa
derivatã cãtre clasa de bazã :
<construct_cls_derivata >(<L1>) : <construct_cls_baza >(<L2>)
{
// corpul constructorului clasei derivate
}
<L1> reprezintã lista de argumente ale constructorului clasei
derivate, iar < L2> lista de argumente ale constructorului clasei
de bazã. Lista <L1> include lista <L2>.
AObservatii
• Constructorii si destructorul clasei de bazã nu se mostenesc.
• Constructorul clasei de bazã se va executa înaintea
constructorului clasei derivate, iar destructorul clasei derivate
se va executa înaintea destructorului clasei de bazã.
Membrii protejati
Clasele derivate dintr-o clasã de bazã nu au acces la membrii
privati ai acesteia. În cazul în care trebuie accesati anumiti
membrii ai clasei de bazã, acestia se vor declara în sectiunea
protected a clasei de bazã, ei devenind astfel, membrii protejati.
Sectiunea protected oferã un nivel intermediar de protectie între
accesul privat si cel public. Membrii protejati ai unei clase de
bazã pot fi accesati de cãtre membrii si prietenii (functiile
friend ) clasei de bazã, precum si de cãtre membrii si prietenii
clasei derivate.
Programul P3.3 prezintã un exemplu de utilizare a membrilor
protejati ai clasei de bazã A1 de cãtre clasa derivatã A12. Astfel,
functia afisareXYZ () din clasa derivatã A12 acceseazã membrii
protejati ai clasei de bazã A1.

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -84
// fisierul sursa P3_3.cpp
#include <iostream.h>
// clasa de baza A1
class A1 {
protected:
int X, Y;
public:
void setXY(int, int);
};
void A1::setXY(int a, int b)
{
X=a;
Y=b;
}
// clasa A12 derivata din clasa de baza A1
class A12:public A1 {
int Z;
public:
void setZ(int);
void afisareXYZ();
};
void A12::setZ(int t)
{
Z=t;
}
void A12::afisareXYZ()
{
// acceseaza direct membrii protejati ai clasei de baza A1
cout<<"\n X = "<<X<<"\t Y = "<<Y<<"\t Z = "<<Z;
}
void main()
{
A12 ob1;
// apeleaza functia publica setXY mostenita din clasa A1
ob1.setXY(5,7);
ob1.setZ(17);
ob1.afisareXYZ();
}
Programul P3.3

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -85
Redefinirea membrilor unei clase de bazã
într-o clasã derivatã
O clasã derivatã poate redefini o functie membru a clasei de
bazã prin introducerea unei versiuni noi a functiei, cu aceeasi
signaturã (adicã, acelasi antet, acelasi prototip). În acest caz, al
pãstrãrii signaturii functiei, operatia de modificare a functiei
mostenite se numeste redefinire (function overriding ). În cazul
în care nu se pãstreazã signatura functiei, operatia se numeste
supraîncãrcarea functiei ( function overloading ). Un astfel de
exemplu, de supraîncãrcare, apare în cazul constructorilor unei
clase.
Programul P3.4 ilustreazã modul de redefinire a unei functii
afisare (), functie membru a clasei de bazã NumarComplex în
clasa derivatã NumarReal .
// fisierul sursa P3_4.cpp
#include <iostream.h>
// clasa de baza NumarComplex
class NumarComplex {
protected:
double re, im;
public:
NumarComplex(double, double);
void afisare();
};
NumarComplex::NumarComplex(double Re, double Im)
{
re=Re;
im=Im;
}
void NumarComplex::afisare()
{
cout<<"\n Numarul complex este "<<re<<"+"<<im<<"i";
}
Programul P3.4 (1/2)

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -86
// clasa NumarReal derivata din clasa de baza NumarComplex
class NumarReal:public NumarComplex {
public:
NumarReal(double x):NumarComplex(x, 0.0)
{};
void afisare();
};
void NumarReal::afisare()
{
cout<<"\n Numarul real este "<<re;
}
void main()
{
NumarReal ob1 = NumarReal(10);
NumarComplex ob2 = NumarComplex(-2,5);
ob1.afisare();
ob2.afisare();
}
Programul P3.4 (2/2)
AObservatii
• Dacã o functie redefinitã într-o clasã derivatã este apelatã de
un obiect al clasei derivate se va apela automat versiunea din
clasa derivatã. În cazul în care este apelatã de un obiect al
clasei de bazã se va apela automat versiunea din clasa de
bazã.
• În general, versiunea functiei din clasa derivatã apeleazã
versiunea din clasa de bazã si realizeazã anumite operatii
suplimentare. Apelul versiunii din clasa de bazã trebuie sã fie
precedat de domeniul de acces al clasei de bazã. În caz
contrar, se va declansa un apel recursiv infinit care va
conduce la aparitia unei erori la momentul executiei
programului.

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -87
Mostenirea publicã si mostenirea privatã
Limbajul C++ presupune în mod implicit cã mostenirea este
privatã.
Astfel,
class T1 : T { //… };
declar ã clasa T1 ca fiind o clasã derivatã privatã a clasei T.
Specificarea mostenirii publice se realizeazã astfel :
class T1 : public T { // … };
Mostenirea privatã poate fi eficientã în limbajul C++ doar în
anumite situatii bine definite. De exemplu, pentru a defini o
clasã reprezentând o stivã se poate începe cu o clasã care
implementeazã o listã, mostenitã privat astfel încât operatiile
listei sã nu fie vizibile si apoi se definesc operatorii de tip push
(pune element în stivã) si pop (scoate element din stivã) în
functie de operatorii listei. Rezultatul este o clasã care poate fi
utilizatã doar ca o stivã. Recomandarea este de a evita o astfel de
situatie, astfel ca mostenirea sã fie folositã în mod consistent.
Acest lucru se poate realiza prin redefinirea operatorilor listei în
clasa stiva sau prin implementarea stivei ca o clasã de sine
stãtãtoare (ne-derivatã) cu un câmp de date care contine lista
(structura stivei, de fapt).
Exemplu :
Considerãm clasa Lista definitã astfel :
class Lista {
public:
Lista();
void insereaza(int); // inse reaza in fata listei un element
int PrimulElem(); // intoarce primul element din lista
int lung(); // numarul de elemente din lista
int include(int); // testeaza daca elementul apare in lista
void elimina(int); // elimina un element din lista
};

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -88
Definim clasa Multime derivatã din clasa Lista .
class Multime : public Lista {
public:
Multime();
void adauga(int); // adauga un element in multime
int marime(); // cardinalul multimii
};
Multime :: Multime() : Lista()
{
// nu sunt necesare initializari
}
void Multime :: adauga(int a)
{
// adauga un element doar daca el nu apare deja in multime
if (!include (a))
insereaza(a);
}
Se observ ã cã functiile definite în clasa de bazã ( insereaza (),
include ()) sunt utilizate în clasa derivatã.
Definirea clasei derivate Multime conduce la mostenirea
publicã a clasei de bazã Lista .
În continuare, prezentãm o altã modalitate de definire a clasei
Multime , ca fiind derivatã din clasa Lista prin mecanismul de
mostenire privatã.
class Multime : private Lista {
public:
Multime() : L ista() { }
void adauga(int);
int include(int x)
{ return Lista :: include (x); }
int marime()
{ return Lista :: lung(); }
};

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -89
Remarc ãm modalitatea de acces la functiile definite în clasa de
bazã. Astfel, este folosit specificatorul clasei Lista .
AObservatie
• În majoritatea aplicatiilor implementate orientat pe obiecte,
mostenirea publicã este indicatã a se utiliza de cãtre toti
programatorii. În cazuri cu totul speciale se poate utiliza
mostenirea privatã.
Ierarhii de clase
Relatia de derivare conduce la generarea unor ierarhii de clase.
În astfel de ierarhii poate apare atât mostenirea singularã cât si
cea multiplã. În cadrul acestui modul ne vom referi doar la
mostenirea singularã.
În figura 3.2 este prezentatã o ierarhie de clase.
Fig. 3.2 Ierarhie de clase.Persoana
Elev Student Salariat
Arhitect Inginer Medic

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -90
Clasa de bazã a ierarhiei de clase este clasa Persoana . Din
aceastã clasã sunt derivate direct clasele Elev , Student si
Salariat . La rândul ei clasa Salariat este clasã de bazã pentru
clasele Arhitect , Inginer si Medic .
Programul P3.5 prezintã un exemplu de implementare a claselor
Persoana , Salariat , Arhitect , Inginer si Medic .
// fisierul sursa p3_5.cpp
#include <iostream.h>
#include <string.h>
#include <assert.h>
// definitia clasei de baza Persoana
class Persoana {
char* nume;
char* pren;
public:
Persoana(char*, char*);
~Persoana();
void afisare();
};
Persoana::Persoana(char* N, char* P)
{
nume = new char[strlen(N)+1];
assert(nume!=0);
strcpy(nume, N);
pren = new char[strlen(P)+1];
assert(pren!=0);
strcpy(pren, P);
}
Persoana::~Persoana()
{
delete nume;
delete pren;
}
void Persoana::afisare()
{
cout << "\n Nume: "<< nume << " Prenume: " << pren;
}
Programul P3.5 (1/4)

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -91
// definitia clasei Salariat derivata din clasa Persoana
class Salariat : public Persoana {
double salari u;
public:
Salariat(char*, char*, double=0.0);
void seteazaSalariu(double);
void afisare();
};
Salariat::Salariat(char* N, char* P, double S)
:Persoana(N, P)
{
seteazaSalariu(S);
}
void Salariat::seteazaSalariu(double S)
{
salariu = S > 0 ? S : 0 ;
}
void Salariat::afisare()
{
cout << "\n Salariat:";
Persoana::afisare();
cout << "\n Salariu:" << salariu;
}
// definitia clasei Arhitect derivata din clasa Salariat
class Arhitect : public Salariat {
char* domeniu_arhitect;
public:
Arhitect(cha r*, char*, double, char*);
void seteazaDomeniu(char*);
void afisare();
};
Arhitect::Arhitect(char* N, char* P, double V, char* D)
:Salariat(N, P, V)
{
domeniu_arhitect = new char[strlen(D)+1];
assert(domeniu_arhitect!=0);
strcpy(domeniu_arhitect, D);
}
void Arhitect::seteazaDomeniu(char* D)
{
strcpy(domeniu_arhitect, D);
}
void Arhitect::afisare()
{
cout << "\n Arhitect ";
Salariat::afisare();
cout << "\n\t Domeniu de lucru este " << domeniu_arhitect;
}
Programul P3.5 (2/4)

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -92
// definitia clasei Inginer derivata din clasa Salariat
class Inginer : public Salariat {
char* tip_inginer;
public:
Inginer(char*, char*, double, char*);
void seteazaTipInginer(char*);
void afisare();
};
Inginer::Inginer(char* N, char* P, double V, char* T)
:Salariat(N, P, V)
{
tip_inginer = new char[strlen(T)+1];
assert(tip_inginer!=0);
strcpy(tip_inginer, T);
}
void Inginer::seteazaTipInginer(char* T)
{
strcpy(tip_inginer, T);
}
void Inginer::afisare()
{
cout << "\n Inginer ";
Salariat::afisare();
cout << "\n\t Tip inginer " << tip_inginer;
}
// definitia clasei Medic derivata din clasa Salariat
class Medic : public Salariat {
char* specializare;
public:
Medic(char*, char*, double, char*);
void seteazaSpecializare(char*);
void afisare();
};
Medic::Medic(char* N, char* P, double V, char* S)
:Salariat(N, P, V)
{
specializare = new char[strlen(S)+1];
assert(specializare!=0);
strcpy(specializare, S);
}
void Medic::seteazaSpecializare(char* S)
{
strcpy(specializare, S);
}
void Medic::afisare()
{
cout << "\n Medic ";
Salariat::afisare();
cout << "\n\t Specialist " << specializare;
}
Programul P3.5 (3/4)

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -93
void main()
{
Persoana P1=Persoana("Manolescu", "Ioana");
Salariat S1=Salariat("Irimescu", "Silvan", 7000000);
Arhitect A1=Arhitect("Stroescu", "Maria", 15000000,
"design vestimentar");
Inginer I1=Inginer("Terente", "Cornel", 20000000,
"calculatoare");
Medic M1=Medic("Manolescu", "Ileana", 10000000,
"cardiolog");
P1.afisare();
S1.afisare();
A1.afisare();
I1.afisare();
M1.afisa re();
}
Programul P3.5 (4/4)
Mostenirea utilizatã este cea publicã. Functia afisare () a fost
redefinitã în toate clasele derivate, ea apelând varianta din clasa
imediat urmãtoare pe nivelul superior din ierarhia de clase.
De exemplu, functia afisare () din clasa Salariat apeleazã functia
afisare () din clasa Persoana astfel,
Persoana::afisare();
Functia afisare () din clasele Arhitect , Inginer si Medic
apeleazã functia afisare () din clasa Salariat :
Salariat::afisare();
Efectul redefinirii functiei afisare () se va observa la executia
programului P3.5 când se vor crea 5 obiecte, P1, S1, A1, I1, M1
de tip Persoana , Salariat , Arhitect , Inginer , respectiv Medic
si se va apela functia afisare () corespunzãtoare.
Un alt exemplu de utilizare a mecanismului mostenirii publice
este prezentat în programul P3.6.
// fisierul sursa p3_6.cpp
#include <iostream.h>
#include <string.h>
Programul P3.6 (1/2)

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -94
// definitia clasei de baza Fereastra
class Fereastra {
int inaltime;
int latime;
public:
void afisare();
};
void Fereastra :: afisare()
{
cout << "\n Fereastra ";
}
// definitia clasei FereastraText derivata din clasa
Fereastra
class FereastraText : public Fereastra {
char* continut;
int LocatieCursor;
public:
void afisare();
void setLocatieCursor(int);
};
void FereastraText::afisare()
{
cout << "\n Fereastra text – locatie cursor " <<
LocatieCursor;
}
void FereastraText::setLocatieCursor(int L)
{
LocatieCursor = L;
}
void main()
{
Fereastra F;
FereastraText *tF, *tF1;
tF = new FereastraText;
F = *tF;
tF1 = tF;
F.afisare();
(*tF1).setLocatieCursor(0);
(*tF1).afisare();
}
Programul P3.6 (2/2)
Functia afisare () mostenitã automat de clasa derivatã
FereastraText de la clasa de bazã Fereastra nu utilizeazã
definitia ei din clasa de bazã, ea fiind redefinitã. În functia
main () sunt definite trei obiecte: F de tip Fereastra si douã
obiecte de tip pointer cãtre tipul FereastraText , tF si tF1.
Remarcãm modul de apelare a functiilor membru ale clasei

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -95
FereastraText , setLocatieCursor (), afisare (), în cazul obiec-
telor de tip pointer. În figura 3.3 este prezentatã structura celor
douã clase Fereastra si FereastraText .
Programul P3.7 defineste clasa Carte , clasã de bazã, si clasa
CursUniversitar derivatã din aceasta.
// fisierul sursa p3_7.cpp
#include <iostream.h>
#include <string.h>
#include <assert.h>
// definitia clasei Carte
class Carte {
char* titlu;
char* autor; // primul autor
char* ISBN;
char* editura;
int an_aparitie;
public:
Carte(char*,char*,char*,char*,int);
Carte(char*,char*,char*,int);
~Carte();
void afisare();
};
Programul P3.7 (1/3)Fig. 3.3 Structura claselor Fereastra și FereastraText . inaltime
latime
afisare () inaltime
latime
LocatieCursor
afisare ()
setLocatieCursor ()
Fereastra FereastraText

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -96
Carte::Carte(char* T, char* A, char* I, char* E, int AP)
{
titlu = new char[strlen(T)+1];
assert(titlu!=0);
strcpy(titlu, T);
autor = new char[strlen(A)+1];
assert(autor!=0);
strcpy(autor, A);
ISBN = new char[strlen(I)+1];
assert(ISBN!=0);
strcpy(ISBN, I);
editura = new char[strlen(E)+1];
assert(editura !=0);
strcpy(editura, E);
an_aparitie = AP;
}
Carte::Carte(char* T, char* A, char* I, int AP)
{
titlu = new char[strlen(T)+1];
assert(titlu!=0);
strcpy(titlu, T);
autor = new char[strlen(A)+1];
assert(autor!=0);
strcpy(autor, A);
ISBN = new c har[strlen(I)+1];
assert(ISBN!=0);
strcpy(ISBN, I);
an_aparitie = AP;
}
Carte::~Carte()
{
delete titlu;
delete autor;
delete ISBN;
delete editura;
}
void Carte::afisare()
{
cout<<"\n Titlu carte: " << titlu << "\t Autor: " << autor;
cout<<"\n \t Editura " << editura << "\t ISBN " << ISBN;
cout << "\t An aparitie " << an_aparitie;
}
Programul P3.7 (2/3)

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -97
// definitia clasei CursUniversitar derivata din clasa Carte
class CursUniversitar : Carte {
int tip_curs;
// 0 – colegiu/universitate, 1 – masterat, 2 – doctorat
char* spec; // specializarea studentilor
public:
CursUniversitar(char*,char*,char*,char*,int,int,char*);
void afisare();
};
CursUniversitar::CursUniversitar(char* T, char* A, char *I,
char *E, int AP, int TC, char* S)
:Carte(T,A,I,E,AP)
{
tip_curs = TC;
spec = new char[strlen(S)+1];
assert(spec!=0);
strcpy(spec, S);
}
void CursUniversitar::afisare()
{
Carte::afisare();
cout << "\n\t Curs universitar tip " << tip_curs;
cout<<"\t destinat studentilor de la specializarea "<<spec;
}
void main()
{
Carte Ob1("Fratii Jderi", "M. Sadoveanu",
"943-253657","Albatros",1997);
Ob1.afisare();
CursUniversitar T1("Sisteme expert", "C. Giumale",
"972-143785","Tehnica",2003, 2, "calculatoare");
T1.afisare();
CursUniversitar T2("Compilatoare", "L.D. Serbanati",
"973-755681","Tehnica",2001, 1, "calculatoare");
T2.afisare();
}
Programul P3.7 (3/3)
Functia redefinitã în clasa CursUniversitar este functia
afisare () care utilizeazã varianta din clasa de bazã. Remarcãm
apelul constructorului corespunzãtor din clasa de bazã. În acest
program, clasa Carte are definiti doi constructori, iar
constructorul clasei derivate CursUniversitar va apela varianta
corespunzãtoare a constructorului clasei de bazã.

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -98
Rezumat
• Relatia de derivare reprezintã definirea unei noi clase prin
extinderea uneia sau a mai multor clase existente. Noua clasã
se numeste clasã derivatã , iar clasele existente din care a fost
derivatã se numesc clase de bazã .
• Mostenirea este mecanismul care permite unei clase A sã
mosteneascã proprietãtile unei clase B. Obiectele clasei A au
astfel acces la atributele si metodele clasei B fãrã necesitatea
de a le redefini.
• O clasã derivatã poate fi la rândul ei clasã de bazã pentru noi
clase. Astfel, se poate genera o ierarhie de clase .
• În cazul în care o clasã de bazã si una derivatã contin
constructori si destructori, constructorii sunt executati în
ordinea derivãrii, iar destructorii în ordine inversã.
• Constructorii si destructorul clasei de bazã nu se mostenesc.
• Clasele derivate dintr-o clasã de bazã nu au acces la membrii
privati ai acesteia. În cazul în care trebuie accesati anumiti
membrii ai clasei de bazã, acestia se vor declara în sectiunea
protected a clasei de bazã, ei devenind astfel, membrii
protejati. Sectiunea protected oferã un nivel intermediar de
protectie între accesul privat si cel public.

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -99
• Membrii protejati ai unei clase de bazã pot fi accesati de
cãtre membrii si prietenii (functiile friend ) clasei de bazã,
precum si de cãtre membrii si prietenii clasei derivate.
• O clasã derivatã poate redefini o functie membru a clasei de
bazã prin introducerea unei versiuni noi a functiei, cu aceeasi
signaturã . În cazul pãstrãrii signaturii functiei, operatia de
modificare a functiei mostenite se numeste redefinire
(function overriding ). În cazul în care nu se pãstreazã
signatura functiei, operatia se numeste supraîncãrcarea
functiei ( function overloading ).
• Limbajul C++ presupune în mod implicit cã mostenirea este
privatã. Cu toate acestea, mostenirea publicã este
recomandatã a se utiliza în majoritatea aplicatiilor imple-
mentate orientat pe obiecte.

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -100
Notiuni fundamentale
Derivare
Mostenire
Clasã de bazã, superclasã, clasã pãrinte
Clasã derivatã, subclasã, clasã copil
Ierarhie de clase, graf de mostenire
Membrii protejati
Sectiunea protected
Redefinirea unei functii (function overriding )
Supraîncãrcarea unei functii (function overloading )

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -101
Teste de autocontrol
3.1 Definiti relatia de derivare.
3.2 Definiti mostenirea.
3.3 Dacã din clasa X se genereazã o clasã Z cum se numesc cele
douã clase ?
(a) X clasã derivatã, Z clasã de bazã
(b) X superclasã, Z subclasã
(c) X clasã copil, Z clasã pãrinte
(d) X clasã de bazã, Z clasã derivatã
3.4 Care dintre afirmatiile urmãtoare sunt adevãrate si care sunt
false?
(a) Obiectele unei clase derivate au acces la membrii privati ai
clasei sale de bazã.
(b) Relatia de mostenire este tranzitivã.
(c) Functiile friend ale clasei de bazã se mostenesc de cãtre
clasa derivatã.
(d) Constructorul si destructorul clasei de bazã se mostenesc în
clasa derivatã.
3.5 Selectati rãspunsul corect referitor la ordinea de apelare a
constructorilor si a destructorilor în cazul claselor derivate
dintr-o clasã de bazã .

M. Oprea, Programare orientat ã pe obiecte – curs IFR
–  Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -102
Ordinea de apelare este urmãtoarea :
(a) constructorul clasei derivate
constructorul clasei de bazã
destructorul clasei derivate
destructorul clasei de bazã
(b) constructorul clasei de bazã
constructorul clasei derivate
destructorul clasei derivate
destructorul clasei de bazã
(c) constructorul clasei derivate
constructorul clasei de bazã
destructorul clasei de bazã
destructorul clasei derivate
(d) constructorul clasei de bazã
constructorul clasei derivate
destructorul clasei de bazã
destructorul clasei derivate
3.6 Dati exemple de relatii de derivare directã.
3.7 Existã diferente între redefinirea si supraîncãrcarea unei
functii ? Justificati rãspunsul.
3.8 Dati un exemplu de functie membru a unei clase care poate
fi supraîncãrcatã.
3.9 În ce situatie se vor declara protejati membrii unei clase de
bazã?
3.10 Care este avantajul principal oferit de mecanismul
mostenirii ?

Modulul 3 – Mostenire
 Mihaela M. Oprea, Programare orientatã pe obiecte
– curs pentru învãtãmântul cu frecventã redusã -103
Exercitii
T3.1 Scrieti un program care defineste clasa de bazã Aparat si
clasa derivatã Radio . Printre functiile membru includeti si o
functie de afisare a datelor membru ale clasei. În programul
principal se vor crea douã obiecte ob1 al clasei Aparat si ob2 al
clasei Radio si se vor apela functiile de afisare.
T3.2 Redefiniti functia de afisare a clasei Aparat în clasa
Radio si rescrieti programul de la exercitiul T3.1.
T3.3 Rescrieti programul de la exercitiul T3.2 realizând
supraîncãrcarea constructorului clasei derivate Radio .
T3.4 Destructorii pot fi supraîncãrcati ? Justificati rãspunsul.
T3.5 Care sunt erorile din urmãtoarea secventã de program ?
// …
class A {
int a,b;
public:
A(int , int, double);
void afisare();
// …
protected:
double t;
};
// …
class B::public A {
double w;
public:
B(int, int, double);
void afisare();
void setValori(i nt x, int y, double z)
{ a=x; b=y; t=z;}
};
// …

Similar Posts