13.02. Interfejsi
U prethodnim lekcijama obrađene su apstraktne klase, koje omogućavaju da se definiše zajednička osnova za više klasa i da se nametne obavezno ponašanje izvedenim klasama. Međutim, apstraktna klasa je i dalje klasa, što znači da može imati polja, može imati implementirane metode i klasa može naslediti samo jednu baznu klasu.
U praksi se često javlja potreba da se klasi nametne određeno ponašanje, ali bez nasleđivanja konkretne klase. U takvim situacijama koristi se interfejs.
Interfejs ne predstavlja objekat, već ugovor koji klasa mora da ispuni.
Pojam interfejsa
Interfejs je tip koji:
- sadrži samo definicije metoda (bez implementacije),
- ne sadrži polja,
- ne može imati konstruktore,
- ne može se instancirati,
- služi za definisanje obaveznog ponašanja klase.
Interfejs se definiše pomoću ključne reči interface.
Primer:
interface IPrintable
{
void Stampaj();
}
📌 Po konvenciji, imena interfejsa počinju slovom I.
Implementacija interfejsa
Klasa implementira interfejs koristeći operator : . Sve metode iz interfejsa moraju biti implementirane.
class Racun : IPrintable
{
public void Stampaj()
{
Console.WriteLine("Stampanje racuna");
}
}
Napomena: Ako neka metoda nije implementirana → greška pri kompajliranju.
U Main metodi kreirati jedan objekat klase Racun i pozvati njegovu metodu stampaj():
Racun R1 = new Racun();
R1.Stampaj();
Interfejs i nasleđivanje klasa
Klasa može:
- naslediti jednu baznu klasu,
- implementirati jedan ili više interfejsa.
Primer:
interface ISacuvaj
{
void Sacuvaj();
}
class Dokument
{
int BrojStrana;
}
class Izvestaj : Dokument, ISacuvaj
{
public void Sacuvaj()
{
Console.WriteLine("Dokument sacuvan");
}
}
U Main metodi:
Izvestaj i1 = new Izvestaj();
i1.Sacuvaj();
Napomena: Redosled koji se navodi nakon dvotačke:
-
bazna klasa
-
interfejsi
Višestruka implementacija interfejsa
Za razliku od klasa, interfejsi podržavaju višestruko nasleđivanje.
Za kreiranje druge verzije - klase Racun2 - implementiraćemo oba interfejsa:
class Racun2 : IPrintable, ISacuvaj
{
public void Stampaj()
{
Console.WriteLine("Stampanje racuna");
}
public void Sacuvaj()
{
Console.WriteLine("Racun sacuvan");
}
}
U Main-u:
Racun2 R2 = new Racun2();
R2.Stampaj();
R2.Sacuvaj();
Interfejs koji implementira drugi interfejs
Interfejs može da implementira drugi interfejs.
interface IRadnja
{
void Izvrsi();
}
interface ILogovanje : IRadnja
{
void Log();
}
Klasa mora implementirati sve metode iz oba interfejsa.
class Akcija : ILogovanje
{
public void Izvrsi()
{
Console.WriteLine("Izvrsavanje");
}
public void Log()
{
Console.WriteLine("Logovanje");
}
}
// u metodi Main:
Akcija A1 = new Akcija();
A1.Izvrsi();
A1.Log();
Interfejs kao ugovor
Interfejs ne govori kako se nešto radi, već šta mora da postoji.
Na primer:
- interfejs kaže: „moraš imati metodu
Stampaj()“ - klasa sama odlučuje kako će ta metoda biti implementirana
Poređenje: apstraktna klasa i interfejs
Apstraktna klasa
- jeste klasa
- može imati polja i konstruktore
- može imati implementirane metode
- može imati apstraktne metode
- klasa može naslediti samo jednu apstraktnu (ili običnu) klasu
Interfejs
- nije klasa
- nema polja ni konstruktora
- nema implementacije metoda
- definiše samo obavezne metode
- klasa može implementirati više interfejsa
Preporuka za buduću praksu (pojednostavljeno):
- koristiti apstraktnu klasu kada postoji zajednička logika
- koristiti interfejs kada postoji samo zajedničko ponašanje
Primer (apstraktna klasa + interfejs)
abstract class Uredjaj
{
public abstract void Ukljuci();
}
interface IInternet
{
void PoveziSe();
}
class Telefon : Uredjaj, IInternet
{
public override void Ukljuci()
{
Console.WriteLine("Telefon ukljucen");
}
public void PoveziSe()
{
Console.WriteLine("Povezan na internet");
}
}
👉 Klasa Telefon:
- nasleđuje ponašanje iz apstraktne klase
- implementira dodatno ponašanje iz interfejsa
Zadaci za vežbu
Zadatak 1: Napraviti interfejs IVozilo sa metodom Pokreni(). Zatim napraviti klase Automobil i Motocikl koje implementiraju taj interfejs.
<-- *** -->
Zadatak 2: Napraviti interfejse IStampanje i ISacuvaj. Nakon toa napraviti klasu Faktura koja implementira oba interfejsa.
<-- *** -->
Zadatak 3: Napraviti apstraktnu klasu Osoba i interfejs IZaposleni. Nakon toga napraviti klasu Profesor.
<-- *** -->
Najčešće greške:
- pokušaj pravljenja objekta interfejsa
- zaboravljena implementacija neke metode
- mešanje pojmova interfejs i apstraktna klasa
- pokušaj nasleđivanja više klasa