Prvo što moraš da shvatiš je da poenta nasledjivanje u OO jezicima nije samo da izvučeš neke zajedničke osobine nekih klasa, da implementiraš te zajedničke osobine i da ih nasledjuješ kako bi "uštedio prostor" tj manje kodirao. Poenta nasledjivanja je da iskoristiš osobinu polimorfizma i dinamičkog vezivanja. Konkretan primjer:
želiš da napraviš neka vozila (kamion, automobil....), a pored toga želiš da napraviš servis za sva vozila. Kako ćeš to uraditi? Možeš da napraviš klasu ServisVozila i da implementiraš metod u toj klasi za svako vozilo, npr
Code:
public void popraviKamion(Kamion klijent){
// provjeri auspuh
klijent.podaciAuspuh();
//...
// provjeri kocnice
klijent.podaciKocnice();
//...
}
public void popraviAutomobil(Automobil klijent){
// provjeri auspuh
klijent.podaciAuspuh();
//...
// provjeri kocnice
klijent.podaciKocnice();
//...
}
ili da iskoristiš nasledjivanje, pa da ubješ više muva jednim udarcem, i omogućiš servisu da popravlja i neka druga vozila. Napraviš Abstraktnu klasu Vozilo koje ima ove metode (podaciAuspuh(),podaciKocnice()..). Ukoliko je za svako vozilo identična implementacija nekog metoda, implementiraš ga odmah u abstraktnoj klasi, ukoliko nije, metod proglasiš abstraktnim. Zatim napraviš nove klase (Automobil,Kamion..) koje nasledjuju abstraktnu klasu Vozilo, i implementiraš za svaku vrstu vozila metode koje su abstraktne u nadklasi, odnosno koje su specifične za svaku vrstu vozila. Zatim ćeš u klasi ServisVozila da napraviš samo jedan metod, koji kao parametar prima objekat tipa Vozilo i radi sa njim. Da li ćeš kasnije tom servisu da proslijediš Automobil, Kamion ili neko drugo vozilo , to nije ni bitno. Osobina koja se zove "dinamičko vezivanje" će da "skontao" šta je tu ustvari prosledjeno i da uradi ono što treba sa datim objektom.
To je poenta nasledjivanja.
Nasledivanje se, u Javi, može obezbjediti direktnim nasledjivanjem klase. Kako Java ne prepoznaje višestruko nasledjivanje(da jedna klasa nasledi više drugih klasa), to se "simulira" preko interfejsa. Ako ponovo pogledaš gornji primjer vidjećeš da bi program radio apsolutno isto ukoliko bi umjesto apstraktne klase koristio interfejs Vozilo, a u vrstama vozila(automobil,kamion) implementirao taj interfejs...
Abstraktna klasa i interfejs, su u ovom smislu, skoro pa ekvivalentni.
Abstraktna klasa se koristi ukoliko znaš koje sve metode i osobine želiš da izdvojiš za neki skup klasa, i ukoliko neke metode znaš kako da implementiraš tako da implementacija odgovara svim "podklasama", ali ne znaš kako da implementiraš sve (npr podaci za aspuh se dobijaju isto za svako vozilo i taj metod implementiraš, dok se podaci za kočnice ne dobijaju isto za automobil i kamion, pa taj metod ne implementiraš(ključna riječ abstract), i ostaviš podklasama da svaka implementira po svojim potrebama). Nedostatak abstraktne klase je to što je njena svrha da je neko naslijedi, te taj neko neće moći da naslijedi ni jednu drugu klasu.
Interfejs nije klasa, tako da ne zauzima to mjesto za nasledjivanje, i može ga implementirati svako, pošto svako može implementirati beskonačno mnogo interfejsa. Sa druge strane interfejs ne može sam da implemnetira ni jedan metod, za razliku od abstraktne klase, te ćeš možda morati malo više da kucaš ukoriko koristiš njega.
Ja jako rijetko koristim abstraktne klase, uvjek ću prije iskoristiti interfejs. To ne znači da ne trebaš da koristiš abstraktne klase, nego da ih ja, iz navike, zaobilazim.
Pozdrav