Korištenje ključne riječi Final sa nasljeđivanjem u Javi

Dok je jedan od Java je prednosti je pojam nasljeđivanja u kojem klasa mogu poticati od drugog, ponekad je poželjno spriječiti nasljeđivanje od strane druge klase. Da biste spriječili nasljeđivanje, prilikom izrade klase koristite ključnu riječ "završno".

Na primjer, ako je vjerovatno da će klasu koristiti drugi programeri, možda želite spriječiti nasljeđivanje ako bi bilo koja kreirana podklasa mogla uzrokovati probleme. Tipičan primjer je Klasa gudača. Ako smo željeli stvoriti potklasu String:

MyString u javnoj klasi proširuje string {
}

Suočili bismo se s ovom pogreškom:

 ne može naslijediti od konačnog java.lang. Niz 

Dizajneri klase String shvatili su da nije kandidat za nasljedstvo i spriječili su je da se produži.

Zašto spriječiti nasljeđivanje?

Glavni razlog za sprečavanje baština jest osigurati da se klasa ponaša ne oštećuje podrazred.

Pretpostavimo da imamo račun klase i podrazred koji ga proširuje, OverdraftAccount. Račun klase ima metodu getBalance ():

 javni dvostruki getBalance ()

{

 vratiti ovo.balance;

 } 

instagram viewer

U ovom trenutku naše rasprave, podrazred OverdraftAccount nije nadjačao ovu metodu.

(Bilješka: Za drugu raspravu o korištenju klasa računa i prekoračenja računa pogledajte kako a podrazred se može tretirati kao superklasa).

Kreirajmo instancu svake klase Account i OverdraftAccount:

 Account bobsAccount = novi račun (10);

 bobsAccount.depositMoney (50);

 OverdraftAccount jimsAccount = novi OverdraftAccount (15.05.500,0.05);

 jimsAccount.depositMoney (50);

 // stvoriti niz objekata računa

 // možemo uključiti jimsAccount jer mi 

 // žele ga tretirati samo kao objekt računa

 Račun [] računi = {bobsAccount, jimsAccount};


 // za svaki račun u nizu prikazuje stanje

 za (Račun a: računi)

 {

 System.out.printf ("Stanje je% .2f% n", a.getBalance ());

 }

 Izlaz je:

 Saldo je 60,00

 Stanje je 65,05 

Čini se da sve djeluje kako se očekuje, ovdje. Ali što ako OverdraftAccount nadjača metodu getBalance ()? Ništa ga ne može spriječiti da radi ovako nešto:

 Javna klasa OverdraftAccount proširuje račun {


 privatni dvostruki overdraftLimit;

 privatni dvostruki overdraftFee;


 // nije uključena ostala definicija klase


 javni dvostruki getBalance ()

 {

 povratak 25,00;

 }

 } 

Ako se primjer gornjeg koda ponovo izvrši, izlaz će biti drugačiji, jer se ponašanje thegetBalance () u klasi OverdraftAccount poziva za jimsAccount:

 Izlaz je:

 Saldo je 60,00

 Stanje je 25,00 

Nažalost, podrazred OverdraftAccount će nikada osigurati ispravan saldo jer smo oštetili ponašanje klase računa nasljeđivanjem.

Ako dizajnirate klasu koju će koristiti drugi programeri, uvijek razmislite o implikacijama potencijalnih potklasa. To je razlog što se klasa stringova ne može proširiti. Izuzetno je važno da programeri znaju da se prilikom stvaranja String objekta uvijek ponaša kao String.

Kako spriječiti nasljeđivanje

Da bi se zaustavilo proširenje klase, deklaracija klase mora izričito reći da se ne može naslijediti. To se postiže korištenjem ključne riječi "završno":

 Račun za javnu završnu klasu {


 } 

To znači da klasa računa ne može biti superklasa, a klasa OverdraftAccount više ne može biti njezin podrazred.

Ponekad biste mogli ograničiti samo određena ponašanja superklase kako biste izbjegli korupciju podrazreda. Na primjer, OverdraftAccount i dalje može biti podrazred računa, ali ga treba spriječiti da nadjača getBalance () metodu.

U ovom slučaju koristite "ključnu" ključnu riječ u deklaraciji metode:

 Račun u javnoj klasi {


 privatni dvostruki saldo;


 // nije uključena ostala definicija klase


 javni konačni dvostruki getBalance ()

 {

 vratiti ovo.balance;

 } 

 } 

Primijetite kako se konačna ključna riječ ne upotrebljava u definiciji klase. Mogu se stvoriti potklase računa, ali one više ne mogu nadjačati getBalance () metodu. Bilo koji kôd koji poziva tu metodu može biti siguran da će raditi onako kako je izvorni programer namijenio.