Razlika između Java apstraktne klase i interfejsa — sve što treba da znate, detaljno objašnjeno
"Sanmej, u prethodna dva članka detaljno smo upoznali Java apstraktnu klasu i Java interfejs, a u ovom ćemo se fokusirati na razliku između apstraktne klase i interfejsa", rekao sam Sanmej, spuštajući miš i tastaturu i okrećući se njoj s desne strane.
"Dobro. Volela bih da to malo sumiram, da sažmem priču o apstraktnoj klasi i interfejsu", odgovorila je Sanmej.
01,Apstraktna klasa
U Javi se klasa definisana ključnom reči abstract naziva apstraktna klasa. Java je objektno-orijentisani jezik, pa se svi objekti opisuju pomoću klasa; ali obrnuto — nisu sve klase namenjene opisivanju objekata, a apstraktna klasa je jedna od takvih.
Sledeći primer prikazuje jednostavnu apstraktnu klasu:
// Lično smatram da svaki trener mora biti jak u odbrani i u napadu
abstract class Coach {
public abstract void defend();
public abstract void attack();
}02,Interfejs
Znamo da se klasa koja ima apstraktne metode naziva apstraktna klasa, što znači da apstraktna klasa može sadržati i metode koje nisu apstraktne. Takva klasa ne može se smatrati čistim interfejsom, iako može pružiti funkciju interfejsa — može se reći da je apstraktna klasa neka srednja staza između obične klase i interfejsa.
Interfejs (engl. Interface) u Javi je apstraktni tip, skup apstraktnih metoda; interfejs se definiše ključnom reči interface. Razlike između interfejsa i apstraktne klase su:
- Apstraktna klasa može imati metode s telom metode, dok interfejs ne može (pre Jave 8).
- Članske promenljive u interfejsu implicitno su
static final, dok u apstraktnoj klasi nisu.
- Članske promenljive u interfejsu implicitno su
- Jedna klasa može implementirati više interfejsa, ali nasleđuje samo jednu apstraktnu klasu.
Sledeći primer prikazuje jednostavan interfejs:
// implicitno abstract
interface Coach {
// implicitno public
void defend();
void attack();
}- Interfejs je implicitno apstraktan, pa prilikom deklaracije nema potrebe koristiti ključnu reč
abstract; - Svaka metoda interfejsa implicitno je apstraktna, pa takođe ne zahteva ključnu reč
abstract; - Metode interfejsa implicitno su
public.
03,Razlike između njih
"O, razumem, brate. Neka te pitam još nešto: koja je razlika između apstraktne klase i interfejsa?"
"Oh, Sanmej, to pitanje je baš na mestu, pogodilo je samo srce stvari", nisam mogao a da podignem palac za Sanmej.
1) Na nivou sintakse
- Apstraktna klasa može pružiti detalje implementacije članskih metoda, dok interfejs može sadržati samo
public abstractmetode; - Članske promenljive apstraktne klase mogu biti različitih tipova, dok članske promenljive interfejsa mogu biti samo tipa
public static final; - Interfejs ne može sadržati statičke blokove koda, dok apstraktna klasa može;
- Jedna klasa može naslediti samo jednu apstraktnu klasu, ali može implementirati više interfejsa.
2) Na nivou dizajna
Apstraktna klasa predstavlja apstrakciju jedne vrste stvari, odnosno apstrakciju klase — između podklase koja nasleđuje apstraktnu klasu i same apstraktne klase postoji odnos is-a. Interfejs je apstrakcija ponašanja. Apstraktna klasa apstrahuje klasu u celini (uključujući svojstva i ponašanje), dok interfejs apstrahuje samo deo klase (ponašanje).
Uzmimo jednostavan primer: avion i ptica su različite vrste stvari, ali imaju jedno zajedničko svojstvo — mogu da lete. Pri dizajniranju možemo avion predstaviti klasom Airplane, pticu klasom Bird, ali ne možemo i letenje predstaviti kao klasu, jer je to samo osobina ponašanja, a ne apstraktni opis jedne vrste stvari.
Tada letenje možemo dizajnirati kao interfejs Fly s metodom fly(), a zatim Airplane i Bird neka prema svojim potrebama implementiraju interfejs Fly. Što se tiče različitih vrsta aviona, poput borbenih i putničkih, neka jednostavno naslede Airplane; slično je s pticama — različite vrste ptica nasleđuju klasu Bird. Ovdje se vidi da je nasleđivanje odnos "da li jeste", dok implementacija interfejsa jeste odnos "da li ima". Ako klasa nasledi neku apstraktnu klasu, podklasa nužno pripada vrsti te apstraktne klase; implementacija interfejsa jeste odnos "ima li, poseduje li", npr. da li ptica može da leti (odnosno da li poseduje osobinu letenja) — ako može leteti, neka implementira taj interfejs, a ako ne može, ne implementira ga.
Interfejs je apstrakcija nekog ponašanja klase i između interfejsa i klase ne postoji jaka veza. Na primer, sve klase mogu implementirati interfejs Serializable i time steći sposobnost serijalizacije, ali se ne može reći da između svih klasa i Serializable postoji odnos is-a.
Apstraktna klasa je, kao roditelj mnogih podklasa, šablonski dizajn. Interfejs je, pak, specifikacija ponašanja, zračeći dizajn. Šta je šablonski dizajn? Najjednostavniji primer — svi smo koristili šablone u PowerPointu: ako je pomoću šablona A napravljeno ppt B i ppt C, onda je zajednički deo B-a i C-a upravo šablon A; ako treba izmeniti taj zajednički deo, menja se samo šablon A, bez potrebe da se ponovo menjaju ppt B i ppt C. S druge strane, zračeći dizajn je poput lifta u koji je ugrađen određeni alarm — jednom kada se alarm ažurira, svi se moraju ažurirati. Drugim rečima, kod apstraktne klase, ako treba dodati novu metodu, može se direktno dodati konkretna implementacija u apstraktnu klasu, a podklase ne moraju da se menjaju; kod interfejsa to nije moguće — ako se interfejs izmeni, sve klase koje ga implementiraju moraju se podrazumnevano prilagoditi.
