CATEGORII DOCUMENTE |
Conceptul de mostenire simpla. Ierarhii de clase
Intre diferitele concepte utilizate in programare se pot face ierarhizari. Conceptul de mostenire este extrem de important in programarea orientata obiect deoarece ea permite crearea clasificarilor ierarhice. Mostenirea este procesul conform caruia un concept, diferit de cel din varful ierarhiei, are toate proprietatile conceptelor care il preced in ierarhia respectiva. Utilizand mostenirea, se poate construi o clasa generala care defineste trasaturile comune ale unui set de elemente corelate. Aceasta clasa poate fi apoi mostenita de catre alte clase, particulare, fiecare adaugand doar acele elemente care ii sunt proprii.
Pentru a ne mentine in terminologia C++ standard, o clasa care este mostenita este numita clasa de baza. Clasa care mosteneste este numita clasa derivata.
Spre exemplu, fie cl1 si cl2 doua clase ale unei ierarhii de clase, cl2 fiind situata pe un nivel imediat inferior nivelului clasei cl1. Atunci clasa cl2 se spune ca este o clasa derivata a clasei cl1, iar cl1 este o clasa de baza a clasei cl2. In acest caz, vom spune ca cl2 mosteneste clasa cl1. Mai departe, o clasa derivata poate fi folosita ca una de baza pentru alta clasa derivata.
Procesul de mostenire inseamna ca o clasa diferita de cea din varful ierarhiei are ca elemente membru, elementele membru ale claselor ce o preced, precum si eventuale alte elemente membru specifice clasei respective. Elementele membru ale clasei aflate in varful ierarhiei sunt elemente comune pentru toate clasele ierarhiei respective.
Controlul accesului la membri mosteniti
Relatia de derivare intre doua clase se exprima la definirea clasei derivate. In acest scop, dupa numele clasei derivate, se scrie lista claselor de baza pentru clasa respectiva folosind ca separator doua puncte. In felul acesta, o clasa derivata se defineste ca mai jos:
class nume_clasa_derivata:lista_claselor_de_baza;
Lista aflata dupa doua puncte indica clasele de baza pentru clasa derivata care se defineste. Lista respectiva contine, pentru fiecare clasa de baza, numele clasei care eventual este precedat de modificatorul de protectie. Ca modificatori de protectie se pot folosi modificatorii public si private. Ca separator intre clasele de baza, se foloseste virgula.
Exemple:
class cl2:cl1 ;
Clasa cl2 este o clasa derivata a clasei cl1. Clasa cl1 este singura clasa de baza a clasei cl2.
class cl2:private cl1;
Clasa cl2 este o clasa derivata a clasei cl1. Clasa cl1 este singura clasa de baza a clasei cl2.
class cl:cl1, public cl2 ;
Clasa cl este o clasa derivata a claselor cl1 si cl2.
Modificatorii de protectie utilizati in lista claselor de baza definesc protectia in clasa derivata a elementelor mostenite.
Daca in lista nu se scrie nici un modificator, implicit acesta este private.
Tabelul de mai jos indica accesul in clasa derivata a elementelor mostenite in functie de protectia fiecarui element mostenit si de modificatorul de protectie utilizat in lista claselor de baza.
Accesul in clasa de baza |
Modificatorul de protectie din lista claselor de baza |
Accesul in clasa derivata a elementului mostenit |
Private Protected Public Private Protected Public |
Private Private Private Public Public Public |
Inaccesibil Private Private Inaccesibil Potected Public |
Dupa cum se vede in tabelul anterior in afara de modificatorii cunoscuti private si public mai este un al treilea modificator protected. Acest modificator este unul recunoscut doar intr-o ierarhie de clase.
Din acest tabel se observa ca o clasa derivata nu are acces la elementele clasei de baza care au protectia private. In schimb, clasa derivata are acces la elementele clasei de baza ce au protectia protected sau public.
De obicei, o ierarhie de clase nu este o ierarhie finala, ea putand fi dezvoltata adaugand clase noi, care deriva din clasele terminale. Aceasta este posibil daca la definirea claselor derivate se utilizeaza, in lista_claselor_ de_baza, modificatorul public in loc de private. In acest caz, elementele protejate prin protected si public se mostenesc in clasa derivata prin aceiasi protectie. De aceea, modificatorul de protectie cel mai des utilizat in este lista_claselor_ de_baza este public.
Exemplu 1:
#include<iostream.h>
#include<math.h>
class numar
int retur()
};
class numar_d1: public numar
void aduna(numar_d1 a, numar b)
};
class numar_d2: public numar_d1
void afis()
};
void main()
Constructorii in ierarhii de clase. Alte probleme in OOP
Relatia dintre clasa derivata si clasele ei de baza ridica unele probleme.
O prima problema este legata de redeclararea datelor membru si supraincarcarea functiilor membru ale claselor de baza in clasa derivata (aceasta a fost rezolvata in urma exemplului anterior). O alta problema este aceea a relatiilor dintre constructorii si destructorii clasei derivate si ai claselor de baza. In sfarsit, o a treia problema este legata de conversiile obiectelor claselor derivate spre cele ale claselor de baza, precum si a pointerilor spre astfel de obiecte.
Constructorii si destructorii sunt functii membru care nu se mostenesc.
La instantierea unui obiect al unei clasei derivate se apeleaza atat constructorii clasei derivate cat si cei ai claselor de baza. Intai se apeleaza constructorii claselor de baza si la urma se apeleaza si constructorii clasei derivate. Ordinea de apel a constructorilor claselor de baza corespunde cu ordinea in care sunt indicate clasele respective in lista_claselor_ de_baza din definitia clasei derivate.
La distrugerea unui obiect al clasei derivate, destructorii se apeleaza in ordinea inversa. Deci, intai se apeleaza destructorul clasei derivate si apoi se apeleaza destructorii claselor de baza in ordinea inversa fata de ordinea de apel a constructorilor la instantierea obiectului respectiv.
Exemplu 2:
#include<iostream.h>
class numar
int& retur()
friend ostream& operator<<(ostream& out,numar a)
};
class numar_d: public numar
/*
- unui obiect dintr-o clasa de baza i se poate atribui un obiect al unei clase care este derivata din ea
- unui obiect al unei clase derivate nu i se poate atribui un obiect al clasei de baza, deoarece o clasa derivata este o completare a unei clase de baza si nu invers
(Putem insa sa inzestram clasa derivata cu o metoda obtinuta prin supraincarcarea operatorului =. Dar si aici datele care aprtin exclusiv exclusiv clasei derivate iau valori arbitrare.)
*/
void operator=(numar & x)
};
void main()
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 2213
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved