Professional Documents
Culture Documents
Java
Trashegimia dhe Nderfaqet
Trashegimia eshte nje mekanizem per te zhvilluar klasat ekzistuese. Nese kemi
nevoje per te implementuar nje klase te re dhe nje klase qe perfaqeson nje concept
me te pergjithshem eshte tashme e disponueshme, atehere klasa e re mund te
trashegoje nga klasa ekzistuese, cdo gje te parapercaktuar duke e mosdeklaruar dy
here apo duke e mbishkruar per nevoja me specifike. Per shembull, Supozojme se
na duhet te percaktojme nje klase me emrin SavingsAccount (LlogariKursimesh), per
te modeluar njellogari qe paguan nje interes fiksmbi depozitat. Ju tashme e keni
llogarine BankAccount dhe nje llogari kursimesh seshte gje tjeter vecse nje lloj
llogarie BankAccount, e vecante! Ne raste te tilla, ben sens qe te perdorim si
konstrukt gjuhe trashegimine. Ja sintaksa per percaktimin e klases ne kete menyre:
Ne Java, cdo klase qe nuk trashegon specifikisht nga nje klase tjeter, atehere kjo
eshte automatikisht nje subclass e klases Object. Klasa Object ka nje numer me te
vogel metodash qe kane kuptim ti aplikohen te gjitha klasave ne Java, si per
shembull: toString() qe ju mund te perdorni per te marre nje string qe pershkruan
gjendjene e objektit.
Figura me poshte eshte nje diagrame klase qe tregon
lidhjet mes tre klasave: Object, BankAccount dhe
SavingsAccount.
Copez kodi:
public class SavingsAccount extends BankAccount
{ public SavingsAccount(double rate)
{ constructor implementation
}
public void addInterest()
{ method implementation
}
private double interestRate;
Copez kodi:
public class SavingsAccount extends BankAccount
{ public SavingsAccount(double rate)
{ interestRate = rate;
}
Sintaksa ne Java:
class SubclassName extends SuperclassName
{ methods
instance variables
}
Example:
public class SavingsAccount extends BankAccount
{ public SavingsAccount(double rate)
{ interestRate = rate;
}
public void addInterest()
{ double interest = getBalance() * interestRate / 100;
deposit(interest);
}
private double interestRate;
}
Qellimi: te percaktojme nje klase te re qe trashegon nga klasa ekzistuese dhe te
percaktojme metodat dhe variablat e instances qe I shtohen klases se re.
Copez kodi:
public void addInterest()
{ double interest = getBalance() * interestRate / 100;
deposit(interest);
}
private double interestRate;
this.deposit(interest);
collegeFund.deposit(interest);
Duket nje objekt superior ne cdo menyre. Atehere pse Savings Account thirret
nenklase dhe BankAccount nje superklase?! Super/sub si terminologji vjen nga
teoria e bashkesive. Nese shohim bashkesine e gjithe llogarive bankare disa prej
tyre jane llogari bankare e te tjera jane objekte SavingsAccount dhe bashkesia e
objekteve SavingsAccount eshte nje nenbashkesi e bashkesive te gjithe objekteve
BankAccount.
Copez kodi:
SavingsAccount collegeFund = new SavingsAccount(10);
BankAccount anAccount = collegeFund;
Kujdes!
Ne nje situate te tille deklarimesh duhet te dime se nga nje reference e tille, nuk
mund te perdorim metoden addInterest, megjithese eshte nuk eshte nje metode e
superklases BankAccount:
anAccount.deposit(1000); // OK
anAccount.addInterest();
Perse dikush do te donte te dinte me pak per nje objekt dhe te ruante nje reference
ne nje variabel objektte superklases? Kjo mund te ndodhe nese doni te riperdorni
kodin qe di per superklasen por jo nenklasen.
Ne mund te perdorim kete metode per te transferuar para nga nje llogari thame, tek
tjetra:
BankAccount momsChecking = . . . ;
BankAccount harrysChecking = . . . ;
momsChecking.transfer(harrysChecking, 1000);
Ju mundet
Metoda transfer() pret nje reference mbi nje obnjekt BankAccount, dhe merr nje
reference mbi nenklase SavingsAccount. Fatmiresisht, ne vend qe te ankohet
kompilatori per mosperputhje tipesh, kompilatori thjesht kopjon referencen e
nenklases collegeFund drejt references se superklases(emri I references other).
Metoda transfer() nuk e di aktualisht kete, Ne kete rast, other I referohet nje
reference Savings Account. Di vetem se other eshte nje BankAccount dhe nuk ka
perse te dije me teper! Ajo per te cilen ai duhet te kujdeset, eshte qe objekti other
mund te trajtoje metoden tone deposit().
Me vone, duam te shtojme interes llogarise, por nuk kemi me akses mbi variablin
original objekt. Eshte e mundur qe ti caktohet nje reference supertipi , nje reference
nentipi! Sidoqofte, nese jemi te sigurte se nje objekt I referohet nje objekti
SavingsAccount, ne mund te perdorim operatorin cast per ta ri-konvertuar prapsh!
Kodi:
Qe kjo te mos ndodhe Java ofron nje operator me emrin instanceOf per te testuar
nese objekti I perket nje klase te vecante. Per shembull:
Kthen true nese tipi I anObject eshte SavingsAccount dhe false ne rast te kundert.
Ndaj eshte e sigurte tem und te programojme si me tej:
SavingsAccount aSavingsAccount;
if (anObject instanceof SavingsAccount)
aSavingsAccount = (SavingsAccount)anObject;
else
aSavingsAccount = null;
Hierarkite e Trashegimise
Ne boten reale ne shpesh perpiqemi te kategorizojme konceptet ne hierarki.
Hierarkite perfaqesohen me shpesh si peme, me konceptin me te pergjithshem ne
rrenje te pemes dhe konceptet me te specializuar ne deget me poshte te
pemes.
Por cfare ndodh kur percaktojme nje variabel me te njejtin emer si ne superklase?!
Per shembull cfare ndodh nese ne perccaktojme nje variabel tjeter me emrin
balance ne klasen SavingsAccount? Ne kete rast cdo objekt SavingsAccount ka dy
variabla instance me te njejtin emer. Variabli I ri I percaktuar hijezon variablin e
superklases. Pra variabli I superklases eshte akoma present por nuk mund te
aksesohet. Sa here qe ne I referohemi metodes balance ne SavingsAccount ne
aksesojme variablin e ri te instances. Sigurisht nese variabli I instances se
superklases eshte privat (dhe keshtu duhet te jene te gjithe, metodat e nenklases
nuk jane te afta ti aksesojne ato variabla. Hijezimi I variablave te instances nuk
eshte I demshem por mund te jete burim konfuzioni!
Ne kete pike kemi nje problem. Ne nuk mundemi thjesht tI shtojme amount-in si
vlere variablit balance:
public class CheckingAccount extends BankAccount
{ public void deposit(double amount)
{ transactionCount++;
// now add amount to balance
balance = balance + amount; // ERROR
}
...
Kemi nje metode te mire per kete qellim, metoden deposit te klases BankAccount.
Atehere duhet te thirrim metoden deposit mbi ndonje objekt- pra parametric
implicit I metodes deposit te klases CheckingAccount. Si e pame ne leksionet me
pare, per te thirrur nje metode tjeter mbi parametrin implicit, nuk specifikojme
parameter por vetem shkruajme emrin e metodes:
public class CheckingAccount extends BankAccount
{ public void deposit(double amount)
{ transactionCount++;
// now add amount to balance
deposit(amount); // not complete
}
...
deposit(amount)
si
this.deposit(amount)
parametric this eshte I tipit CheckingAccount. Kemi nje metode te quajtur deposit
ne klasen CheckingAccount. Prandaj eshte kjo ajo metode qe do thirret- por kjo
eshte vetem metoda qe po whkruajme aktualisht! Kjo metode do therrase veten
gjithe Kohen dhe programi do te bjere nerekursioj te pafund.