CATEGORII DOCUMENTE |
MOSTENIRE. CLASE DE BAZA. CLASE DERIVATE
Una dintre caracteristicile programarii orientate pe obiecte, incapsularea, face posibila aplicarea mecanismului de mostenire Mostenirea consta in preluarea atributelor de la o clasa numita clasa de baza, la o alta clasa numita clasa derivata Ca atare, clasele derivate poseda toate caracteristicile clasei de baza, care pot fi imbunatatite atat functional, cat si structural.
O reprezentare a claselor sub aspectul mostenirii conduce la o ierarhizare, adica o dispunere pe anumite nivele a acestora.
Mostenirea poate fi simpla sau multipla, dupa cum clasa derivata mosteneste caracteristicile de la o clasa de baza sau de la mai multe clase de baza.
Derivarea claselor, in functie de solicitari, reprezinta un proces cu durata variabila, de aceea se recomanda conceperea unor clase de baza cat mai simple.
Procesul de mostenire ofera o serie de avantaje care constau in:
a) posibilitatea utilizarii unui cod comun pentru mai multe clase;
b) obtinerea extensiei unei clase fara a fi necesara o recompilare a clasei initiale;
c) sansa functiilor, care folosesc obiecte din clasa de baza, de a dispune si de obiecte dintr-o clasa derivata a sa.
d) utilizarea polimorfismului in timpul executiei programului prin folosirea functiilor virtuale [L9] etc.
Reutilizarea codului este posibila in programarea orientata pe obiecte, sub doua aspecte:
prin compunere - includerea de obiecte in cadrul altor obiecte;
prin mostenire - crearea unor obiecte folosind o colectie de obiecte existente la un moment dat.
Prin compunere, obiectul, care include un alt obiect, va avea ca elemente membre, toate elementele membre ale obiectului inclus, alaturi de cele specifice lui. Accesul la membrii obiectului inclus se va realiza prin intermediul acestui obiect.
Exemplu:
# include<iostream.h>
class punct
};
class cerc
void main( )
Operatia de derivare obtinuta prin procesul de mostenire constituie o varianta mult imbunatatita de reutilizare a codului.
Sintaxa:
class iden_clasa_derivata: specificator_acces iden_clasa_baza
Accesul la membrii din interiorul clasei derivate este determinat de specificatorul de acces. Accesul in clasa de baza poate fi public, private sau protected. Daca o clasa derivata este de tip class si nu se precizeaza specificatorul de acces, atunci implicit va fi private, iar in cazul clasei derivate de tip struct, va fi public.
Drepturile de acces ale clasei derivate asupra membrilor clasei de baza:
Drept de acces in clasa de baza |
Specificator de acces sau modificatorul de protectie din lista claselor de baza |
Drept de acces in clasa derivata |
PUBLIC PRIVATE PROTECTED |
PUBLIC PUBLIC PUBLIC |
PUBLIC inaccesibil PROTECTED |
PUBLIC |
PRIVATE |
PRIVATE inaccesibil PRIVATE |
In general, protected nu este folosit ca specificator de acces in procesul de mostenire. Rolul sau este de a permite accesarea unor membri care nu fac parte din sectiunea public a clasei de baza, in clasa derivata.
Indiferent de specificatorul de acces (public sau private) folosit, membrii din sectiunea private a clasei de baza nu pot fi direct accesati in clasa derivata. Accesarea lor se face prin functiile membre mostenite de la clasa de baza.
Folosind specificatorul de acces public, se mai spune, ca transformam clasa de baza intr-o clasa publica. Membrii protejati (protected) din clasa de baza raman protejati si in clasa derivata.
Daca se utilizeaza specificatorul de acces private, clasa de baza devine privata si toti membrii declarati public in ea devin privati in clasa derivata. Membrii protejati din clasa de baza devin privati in clasa derivata.
Clasele derivate sunt tratate ca subclase ale clasei de baza, obiectele derivate pot fi atribuite obiectelor clasei de baza, fara a fi necesara conversia de tip. #n astfel de atribuiri se vor copia numai membrii clasei de baza. Astfel de atribuiri nu se pot realiza decat cu obiecte bazate pe relatia de mostenire.
Exemplu:
# include <iostream.h>
class B // def.clasei de baza B
void afis( ) };
class D:public B // def. clasei derivate D
void afis_1( )
};
main( )
Exemplu:
#include<iostream.h>
#include<conio.h>
#include<math.h>
#include<string.h>
class baza
float r_x()
float r_y()
};
class derivata:public baza
};
float ad_1(baza b,derivata d)
float ad_2(baza b,derivata d)
float dif_1(baza b,derivata d)
float dif_2(baza b,derivata d)
void main()
Se observa ca specificatorul de acces fiind public (mostenire publica), obiectele de tip derivat (din clasa derivata) pot accesa direct membrii publici din clasa de baza.
Nu este permisa transformarea unui membru private al clasei de baza intr-un membru public sau protected al clasei derivate.
Conversia de tipul (C_D*)->(C_B*) se poate realiza:
a) implicit, daca specificatorul de acces este public;
b) explicit, cu operatorul cast, daca specificatorul de acces este private.
Conversia de tipul (C_B*)->(C_D*) se poate realiza doar explicit cu operatorul cast.
Aceste conversii, in procesul de mostenire, trebuie facute cu multa atentie, la nivel de pointeri, pentru ca pot conduce la erori greu de detectat. Pentru detalii vezi aI.Muslea - C++..s.
Specificatorul protected asigura o flexibilitate a mecanismului de mostenire. De regula, un membru al unei clase declarat protected nu este accesibil decat membrilor clasei respective. Accesul la un membru protejat este acelasi cu accesul la un membru privat cu o singura exceptie, si anume, membru protejat poate fi mostenit.
Exemplu:
# include<iostream.h>
class B
void afis( )
class D: public B
// este permis accesul in D la membrii protected u si v din B
void afis_1( )
};
main( )
Daca membrii u si v ar fi fost declarati in clasa B private, atunci in D nu s-ar fi permis acces la ei si programul nu s-ar putea compila.
Daca, totusi, se mosteneste o clasa de baza cu protected, atunci membrii publici si protejati ai clasei de baza devin membrii protejati ai clasei derivate.
Exemplu:
# include <iostream.h>
class B
void afis()
class D:protected B
void afis_1( )
main( )
Incorect ar fi:
ob.punct(6,9);
ob.afis( );
pentru ca s-ar folosi membrii protejati ai clasei D, desi sunt declarati publici in clasa B.
Daca o clasa derivata va deveni o clasa de baza pentru o noua clasa derivata, atunci orice membru protejat al clasei de baza initiale (clasa mostenita cu public de catre prima clasa derivata), poate fi mostenit ca protected de a doua clasa derivata.
Exemplu:
# include <iostream.h>
class B
void afis( )
class D_1:public B
// acces corect la u si v
void afis_1( )
class D_2:public D_1
// u si v sunt mosteniti indirect prin clasa D_1. Acces corect
void afis_k( )
main( )
Daca clasa B ar fi mostenita cu specificatorul private, atunci toti membrii din B ar deveni membri private in clasa D_1, ceea ce inseamna ca ei nu vor fi accesibili lui D_2. Totusi, u si v (protected in B) continua sa ramana accesibili lui D_1.
Ca o concluzie, daca clasa de baza B este mostenita cu specificatorul de acces private in clasa derivata D_1, clasa D_1 continua sa aiba acces la membrii declarati public si protected din clasa B. Aceasta proprietate nu se mai poate transmite in continuare.
Intr-o mostenire pot fi folosite mai multe clase de baza (mostenire multipla).
Exemplu:
# include <iostream.h>
class B_1
protected:
int k;
public;
void afis_1( )
class B_2
protected:
int u:
public:
void afis_2( )};
class D:public B_1,public B_2
main( )
Se observa ca trebuie mentionat specificatorul de acces la fiecare clasa de baza mostenita.
Orice functie, care opereaza cu un obiect din clasa de baza, va putea opera si asupra unui obiect din clasa derivata, deoarece clasa derivata include tot ceea ce contine clasa de baza, fara a recompila codul initial al functiei. De aceea este necesar a vedea modul de organizare al fisierelor intr-o astfel de ierarhie.
Exemplu:
#include<iostream.h>
#define PI 3.141;
class Punct
void afis()
class Cerc:public Punct
float aria()
void afis()
void main()
Analizati acest exemplu si precizati principalele sale caracteristici.
Aplicatie:
Sa se implementeze clasele 'carte', 'stare', 'cititor', 'fisa', cu scopul realizarii unei evidente cu privire la posibilitatea de a imprumuta o carte de la biblioteca. Se au in vedere urmatoarele conditii:
cititorul poate imprumuta o singura carte;
fiecare carte este unica in biblioteca;
imprumutul depinde de existenta cartii respective in biblioteca (daca nu este deja imprumutata).
#include<iostream.h>
#include<conio.h>
typedef enum mod_i;
typedef enumstare;
class nod
int i=0,j=0;
char data[8];
class carte
class cititor
;
class fisa:public cititor
void fisa::imprumut(mod_i tip_i,carte& cartea)
else
if(tip_i==ret)
void fisa::actualizare(mod_i tip_i,carte cartea)
if(tip_i==ret)
void fisa::afis_inr(int i)
carte::carte()
void carte::act_stare(stare st)
void carte::afisare()
int cititor::informare(carte& cartea)
void cititor::solicitare(carte& cartea)
void cititor::returnare(carte& cartea)
cititor::cititor()
void main()
1. Sa se realizeze o implementare C++ cu privire la:
1.1 evidenta cartilor din biblioteca la un moment dat;
1.2 evidenta trenurilor de calatori dintr-o gara (nod feroviar);
1.3 evidenta studentilor, baieti si fete, din facultatea de informatica;
Fiecare student isi va propune o implementare care sa satisfaca cat mai exact cerintele enuntate.
2. Pornind de la clasa de baza patrulater, sa se implementeze clase derivate ale acestei clase.
3. Sa se implementeze clase derivate pornind de la clasa de baza grup.
4. Sa se realizeze o implementare a clasei derivate fig_geom_spatiu pornind de la clasa de baza fig_geom_plana (mostenire simpla, mostenire multipla).
5. In una din problemele propuse anterior, sa se foloseasca reutilizarea codului pe baza compunerii in programarea orientata pe obiecte.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 1227
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved