Trashegimia e Klasave ne C++

Trashëgimia e Klasave ne C++ 

Përmes mekanizmit të trashëgimisë (ang. inheritance), anëtarët e klasës
ekzistuese mund të shfrytëzohen gjatë definimit të klasave të reja. Kjo ka një
rëndësi të veçantë, sepse mundësohet plotësimi me komponente i një klase
ekzistuese, gjë që mund të shfrytëzohet gjatë përmirësimit të programeve që janë
në shfrytëzim, ose të përfshira në biblioteka të ndryshme programesh të gatshme.
Klasa ekzistuese njihet si klasë bazë (ang. base class), kurse klasa e re i
trashëgon karakteristikat e klasës bazë dhe quhet klasë e nxjerrë (ang. derived class).
Klasa e re krijohet duke e plotësuar klasën ekzistuese me anëtarë të tjerë,
qofshin ato anëtarë të dhënash ose funksione. Gjatë kësaj, klasa bazë nuk pëson
asnjë ndryshim. Njëkohësisht, klasa e nxjerrë mund të shfrytëzohet si klasë bazë
për nxjerrjen e klasave të tjera. Një mundësi e tillë e krijimit të klasave të reja, si
prej klasave bazë ashtu edhe prej klasave të nxjerra, përmes mekanizmit të
trashëgimisë, paraqet një organizim hierarkik të klasave, gjë që programimin e
orientuar në objekte e bën edhe më të fuqishëm. Dukja e një organizimi hierarkik të klasave
Këtu, nënkuptohet se hierarkia mund të vazhdohet më tutje edhe pas
klasës së nxjerrë Profesori. Gjatë kësaj, shigjetat janë të drejtuara prej klasave
të nxjerra kah klasa bazë dhe përmes tyre tregohet se prej cilës klasë janë nxjerrë
klasat e veçanta.
Nëse analizohet hierarkia e dhënë, do të shihet se klasat e nxjerra, në fakt,
e plotësojnë klasën bazë me të dhëna dhe funksione të tjera. Kështu, p.sh., nëse
te klasa Person përfshihen të dhënat bazike, siç janë emri, vendi, datëlindja etj.,
përmes klasës së nxjerrë Studenti të dhënat bazë plotësohen, p.sh., me të
dhënat për fakultetin, drejtimin e zgjedhur etj. Më tutje, të gjitha këtyre të
dhënave mund t'u shtohen edhe ato për provimet e studentëve (klasa e nxjerrë
Provimet) dhe për pagesat e tyre (klasa e nxjerrë Pagesat).
Meqë shembulli i programit ku do të paraqitej hierarkia e dhënë më sipër,
ose edhe pjesë të saj, kërkon më shumë hapësirë, në vijim do të jepen disa
shembuj më elementarë.
Shembull Programi classT1a, në të cilin definohet klasa Alfa si klasë
bazë dhe klasa Beta - si klasë e nxjerrë prej saj.

// Programi classT1a

  #include <iostream>

using namespace std;

class Alfa

{

private:

int a;

public:

double b;

void Jeta()

{

a=5;

b=8;

cout << "\nVlerat te klasa Alfa"

<< "\n\n a="

<< a

<< "\n b="

<< b

<< "\n\n";

}

};

class Beta:public Alfa

{

private:

double c;

public:

int d;

void Dita()

{

b=2;

c=4;

d=7;

cout << "Vlerat te klasa Beta"

<< "\n\n b="

<< b

<< "\n c="

<< c

<< "\n d="

<< d

<< "\n";

}

};

int main()

{

Alfa X;

Beta Y;

X.Jeta();

Y.Dita();

X.Jeta();

return 0;

}

Në program, fillimisht është definuar klasa Alfa. Te funksioni Jeta i cili
është deklaruar si publik, variablave a dhe b të klasës u janë shoqëruar vlerat
përkatëse 5 dhe 8. Njëkohësisht, përmes komandës cout është urdhëruar
shtypja e këtyre vlerave. Pastaj është definuar klasa Beta, në të cilën, përveç
komponenteve të saj, janë deklaruar si publike edhe komponentet publike të
klasës Alfa, gjë që arrihet përmes deklarimit public Alfa, kështu:

class Beta:public Alfa

Klasa Beta llogaritet si klasë e nxjerrë nga klasa Alfa, meqë brenda saj
shfrytëzohen edhe komponentet publike të klasës Alfa.
   • Brenda klasës Alfa mund të shfrytëzohen vetëm variablat a dhe b, si
     dhe funksioni Jeta. Por, nuk mund të shfrytëzohen variablat c e d, si
     dhe funksioni Dita, të cilët paraqiten në komponentet e klasës së
     nxjerrë Beta.
   • Meqë komponentet publike të klasës Alfa janë deklaruar njëkohësisht si
     publike edhe te klasa Beta, te kjo klasë mund të shfrytëzohet edhe
     variabla b, si dhe funksioni Jeta.
   • Brenda klasës Beta nuk mund të shfrytëzohet variabla a, e cila është
     anëtar i klasës Alfa, por e deklaruara si private.

Në program, fillimisht janë deklaruar objektet X dhe Y të klasave Alfa
dhe Beta. Pastaj, përmes komandave:

X.Jeta();

Y.Dita();

X.Jeta();

dy herë është thirrë funksioni Jeta dhe një herë funksioni Dita, të cilët
përfshihen në komponentet e klasave përkatëse. Nga kjo shihet se, si rezultat i thirrjes dy herë të funksionit Jeta, vlerat që
përcaktohen brenda klasës Alfa janë shtypur dy herë.
Në shembullin e dhënë, deklarimi i objektit X në programin kryesor është i
panevojshëm, sepse pjesa publike e klasës Alfa përfshihet në klasën Beta.
Kështu, programi kryesor mund të shkruhet edhe si në vijim.

int main()

{

Beta Y;

Y.Jeta();

Y.Dita();

Y.Jeta();

return 0;

}

Definimi i funksioneve jashtë klasave

Me qëllim të rritjes së dukshmërisë së klasave, funksionet që shfrytëzohen
brenda tyre edhe në këtë rast mund të definohen jashtë strukturave të tyre, duke
i shfrytëzuar format e zakonshme.
Shembull Versioni classT1b i programit classT1a, në të cilin definimi
i funksioneve bëhet jashtë strukturave të klasave.

// Programi classT1b

 #include <iostream>

using namespace std;

class Alfa

{

private:

int a;

public:

double b;

void Jeta();

};

class Beta:public Alfa

{

private:

double c;

public:

int d;

void Dita();

};

int main()

{

Beta Y;

Y.Jeta();

Y.Dita();

Y.Jeta();

return 0;

}

void Alfa::Jeta()

{

a=5;

b=8;

cout << "\nVlerat te klasa Alfa"

<< "\n\n a="

<< a

<< "\n b="

<< b

<< "\n\n";

}

void Beta::Dita()

{

b=2;

c=4;

d=7;

cout << "Vlerat te klasa Beta"

<< "\n\n b="

<< b

<< "\n c="

<< c

<< "\n d="

<< d

<< "\n";

}

Shfrytëzimi i anëtarëve të mbrojtur

Anëtarët e klasës bazë do të jenë edhe të mbrojtur, duke e shfrytëzuar
specifikuesin e qasjes protected. Këta anëtarë mund të shfrytëzohen plotësisht
njëlloj si edhe anëtarët të cilët përfshihen nën specifikuesin private. Por, për
dallim nga ata nën specifikuesin private, komponentet nën specifikuesin
protected mund të shfrytëzohen edhe te klasat e nxjerra (ato nën specifikuesin
private nuk mund të shfrytëzohen te klasat e nxjerra).
Anëtarëve të klasës bazë me specifikues të qasjes së mbrojtur nuk mund
t'u qasemi nga jashtë sikur edhe atyre me specifikues të qasjes private. Por,
anëtarët e klasës, të cilët janë deklaruar si të mbrojtur, mund të shfrytëzohen
edhe brenda klasave të nxjerra, gjë që nuk është e mundur për anëtarët me
specifikues të qasjes private.
Shembull Versioni classT1c i programit classT1b, në të cilin variabla
b është përfshirë nën specifikuesin e qasjes së mbrojtur.

// Programi classT1c

 #include <iostream>

using namespace std;

class Alfa

{

private:

int a;

protected:

double b;

public:

void Jeta();

};

class Beta:public Alfa

{

private:

double c;

public:

int d;

void Dita();

};

int main()

{

Beta Y;

Y.Jeta();

Y.Dita();

Y.Jeta();

return 0;

}

Pjesa tjetër e programit, që nuk është dhënë, në të cilën përcaktohen
funksionet Jeta dhe Dita, mbetet e njëjtë me atë që shihet te programi
classT1b. Kjo do të thotë se variabla b në komponenten e mbrojtur të klasës
Alfa shfrytëzohet edhe te klasa e nxjerrë Beta.

Shfrytëzimi i anëtarëve gjatë trashëgimisë

Anëtarët e klasës bazë bëhen edhe anëtarë të klasës së nxjerrë. Te klasa e
nxjerrë mund t'u qasemi direkt anëtarëve publikë dhe anëtarëve të mbrojtur të
klasës bazë. Por, nuk lejohet qasja direkte tek anëtarët e mbrojtur të klasës bazë,
prej klasës së nxjerrë. Qasja direkte te anëtarët privat të klasës bazë është e
mundshme vetëm brenda klasës bazë.
Anëtarët publikë të klasës bazë trashëgohen te klasa e nxjerrë si anëtarë
publikë, kurse anëtarët privatë ose të mbrojtur, varësisht nga specifikuesi i qasjes
që zgjedhet gjatë definimit të klasës së nxjerrë, ashtu siç është dhënë në vijim.

1.class Alfa

{

...

};

class Beta:public Alfa

{

...

};

Këtu, anëtarët publikë të klasës Alfa trashëgohen te klasa e nxjerrë Beta
si anëtar publik.

2.class Alfa

{

...

};

class Beta:private Alfa

{

...

};

Në këtë rast, anëtarët publikë të klasës Alfa te klasa e nxjerrë Beta
trashëgohen si anëtar privat.

3.class Alfa

{

...

};

class Beta:Alfa

{

...

};

Meqë këtu nuk është shënuar specifikuesi i qasjes, kompjuteri e nënkupton
atë si private. Prandaj, në këtë rast, si edhe në rastin paraprak, anëtarët publikë
të klasës Alfa trashëgohen si anëtarë privatë te klasa e nxjerrë Beta.

4.class Alfa

{

...

};

class Beta:protected Alfa

{

...

};

Në këtë rast, pasi specifikuesi i qasjes për anëtarët e trashëguar është
protected, anëtarët publikë të klasës Alfa do të jenë anëtarë të mbrojtur te
klasa e nxjerrë Beta.
Pas definimit të klasës së nxjerrë, vlejnë rregullat e qasjes për klasat e
zakonshme, si tek anëtarët e saj, ashtu edhe tek anëtarët e trashëguar nga klasa
bazë.
Klasa bazë nuk ka qasje tek anëtarët e klasës së nxjerrë, përkatësisht prej
saj nuk mund të shihen komponentet e pjesës tjetër të hierarkisë së klasave në të
cilën ajo përfshihet.
Çdo klasë e nxjerrë bëhet klasë bazë për klasat të cilat nxirren prej saj.

Trashëgimia e shumëfishtë

Gjatë krijimit të klasave përmes trashëgimisë, klasa e re mund të nxirret
prej një klase bazë, ose edhe prej më shumë klasave bazë njëkohësisht. Në këto dy
raste flitet për trashëgimi të njëfishtë (ang. single inheritance) dhe trashëgimi të
shumfishtë (ang. multiple inheritance). Te shembujt që u dhanë në pjesën
paraprake kemi të bëjmë me trashëgiminë e njëfishtë, sepse anëtarët e trashëguar
të klasës së nxjerrë janë anëtarë të vetëm një klase bazë. Këtu, klasa e nxjerrë X i trashëgon vetëm anëtarët e klasës bazë A, gjë që,
siç është dhënë më parë, në program shkruhet si në vijim.

class A

{

...

};

class X:public A

{

...

};

Specifikuesi i qasjes te klasa e nxjerrë X, për anëtarët e trashëguar nga klasa
A, siç u pa në shembujt paraprakë, përveç public, mund të jenë edhe private
dhe protected.
Një shembull i trashëgimisë së shumëfishtë, kur klasa X është nxjerrë nga
dy klasat bazë A dhe B.
Gjatë definimit të trashëgimisë nga shembulli në fjalë, definimi i
relacioneve të klasave do të duket si në vijim.

class A

{

...

};

class B

{

...

};

class X:public A,public B

{

...

};

Nënkuptohet se edhe këtu specifikuesit e qasjes te klasa e nxjerrë X, për
anëtarët e trashëguar nga klasat A dhe B, si te rastet e trashëgimisë së njëfishtë,
përveç public, mund të jenë edhe private dhe protected.
Trashëgimia e shumëfishtë mund të jetë edhe komplekse, kur si klasa bazë
paraqiten edhe klasa të nxjerra.

Në program, definimi i relacioneve të klasave në këtë rast do të mund të
shkruhej ashtu siç është dhënë në vijim.

class A

{

...

};

class B:public A

{

...

};

class C:public A

{

...

};

class X:public B,public C

{

...

};

Referim
Agni Dika, "Programimi i Orientuar në Objekte në C++" 2007.

Kategoria:Gjuhë programimi