Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

C# interface-i - svrha

[es] :: .NET :: C# interface-i - svrha

[ Pregleda: 3194 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

darthskywalker
Luka Skajvoker

Član broj: 286923
Poruke: 25
31.176.194.*



+1 Profil

icon C# interface-i - svrha24.06.2012. u 16:59 - pre 144 meseci
Pozdrav,
molim vas da li mi neko moze objasniti na nekim jednostavnim primjerima za sta sluze interface-i u c# ili javi. Nisam uspio da nadjem koja je njihova svrha. Koliko sam shvatio oni samo sadrze potpise funkcija ili sadrze neke varijable, ali ne implementiraju funkcije i ako klasa implementira interface, slaze se da ce implementirati sve metode koje se nalaze u interfaceu. Koliko sam primjetio da bi uporedili dva objekta, klasa mora implementirati interface. Zasto bi klasa implementirala interfejs da bi se mogla uporediti dva objekta, zasto jednostavno bez interfejsa se ne napravi metod koji ce uporedjivati objekte? Eto ako neko ima fino objasnjenje, bio bih zahvalan.
 
Odgovor na temu

boyan3001
BG

Član broj: 284396
Poruke: 424
*.dynamic.sbb.rs.

Sajt: rs.linkedin.com/pub/bojan..


+647 Profil

icon Re: C# interface-i - svrha24.06.2012. u 17:42 - pre 144 meseci
Interfejsi su tu kao garancija kompajleru da odredjena klasa sigurno sadrzi metode koje intefejs propisuje, te je sa njom moguce manipulisati uz pomoc tih metoda. Na ovaj nacin se obezbedjujes da ne dodje do poziva nepostojece metode u nekoj klasi.
Evo ti jedan dobar primer, skoro sam ga radio, gde su mi intefejsi bas odlicno legli.
U pitanju je Yamb. Napravio sam klasu Polje, koja cuva upisanu vrednost u odredjeno polje u tabeli bodova. Polje je samo osnova za dalje izvedene klase. Te klase su npr Jedinice, Dvojke, Trojke... Kenta, Triling, Ful, Kare/Poker i Yamb. Svaka ova izvedena klasa ima algoritam koji proverava kako se dobijena kombinacija uklapa u polje u koje igrac zeli da upise bodove. Te tako, ako ti kliknes npr na polje za Sestice i imas 4 sestice, upisace ti 24. Ako pak kliknes sa istom kombinacijom na Yamb polje, upisace ti krompir (0). E sad vidis, svaka ova izvedena klasa u sustini radi istu stvar, proveri sta igrac ima u svjoj kombinaciji, nadji najpogodniju za zadato polje i upisi rezultat... ali algoritam je zavisno od polja razlicit.
Tako sam ja definisao za sve ove izvedene klase da imaju isti intefejs, u kome je definisana ova metoda. Tako razlicite klase dele istu metodu po imenu, ali svaka metoda ima svoj algoritam kojim daje potreban rezultat.

Potrazi knjigu "Visual C# 20xx Step by Step", u njoj ti je sve odlicno i razumljivo objasnjeno. Ja mozda nisam ovde bas najsretnije srocio sve sto treba.
Realno...
 
Odgovor na temu

Dejan Carić
Oslo, Norway

Član broj: 230976
Poruke: 232
*.dynamic.isp.telekom.rs.

Sajt: www.dcaric.com


+26 Profil

icon Re: C# interface-i - svrha24.06.2012. u 19:38 - pre 144 meseci
Interfejs ti je kao ugovor. On definiše metode, property-e, itd. koje svaka klasa mora da implementira ako implementira i taj interfejs. Evo jedan primer iz prakse.
Definišeš interfejs za snimanje objekta Student u bazu podataka.

Code:
public interface IStudentRepository
{
    Student GetById(int id);
    List<Student> GetAll();
    void Save(Student student);
    void Delete(int id);
}

I sada hoćeš da napraviš konkretnu implementaciju tog interfejsa koja će da koristi EntityFramework za rad sa bazom:
Code:
public class StudentRepositoryEntityFramework : IStudentRepository
{
    public Student GetById(int id)
    {
        // insert some code here
    }

    public List<Student> GetAll()
    {
        // insert some code here
    }

    public void Save(Student student)
    {
        if (student.Id > 0)
            Update(student);
        else
            Create(student);
    }

    private void Create(Student student)
    {
        // insert some code here
    }

    private void Update(Student student)
    {
        // insert some code here
    }

    public void Delete(int id)
    {
        // insert some code here
    }
}

Klasa StudentRepositoryEntityFramework je sklopila ugovor sa interfejsom IStudentRepository. To znači da mora da implementira sve metode koje su definisane u interfejsu IStudentRepository i te metode moraju biti public. Save metoda ne može biti private, internal ili protected, ona mora biti public. Tvoja konkretna implementacija može da sadrži i neke metode koje nisu definisane u interfejsu, kao što su Create, Update, itd., ali sve metode koje su definisane u interfejsu moraju biti implementirane i moraju biti public, ok?

Interfejsi se najviše koriste kod Dependency injection i Inversion of control pattern-a. Dosta je komplikovano u početku da se skapira, ali poenta je sledeća:
Sve što radiš, radiš sa interfejsima, a ne sa konkretnim implementacijama. Zašto?
1. Zbog Unit Testova. Implementaciju možeš uvek da zameniš sa nekim fake objektom.
2. Ako želiš da promeniš implementaciju, tj. nećeš više da koristiš EntityFramework već NHibernate. Ako na 50 mesta u kodu koristiš StudentRepositoryEntityFramework umesto IStudentRepository, onda ćeš na tih 50 mesta morati da zameniš StudentRepositoryEntityFramework sa StudentRepositoryNHibernate. Ako na 50 mesta u kodu koristiš IStudentRepository, onda ćeš izmenu morati da napraviš samo na jednom mestu (na mestu gde se definiše koja klasa se instancira za dati interfejs)!

Citat:
darthskywalker:Koliko sam primjetio da bi uporedili dva objekta, klasa mora implementirati interface. Zasto bi klasa implementirala interfejs da bi se mogla uporediti dva objekta, zasto jednostavno bez interfejsa se ne napravi metod koji ce uporedjivati objekte?


Recimo da smo definisali 3 klase:
Code:
public class Honda
{
    public string Model { get; set; }
}

public class Porsche
{
    public string Model { get; set; }
}

public class Boeing
{
    public string Model { get; set; }
}


Ono što hoćemo da uradimo jeste da napravimo konzolnu aplikaciju koja će iz liste nekih objekata da prepozna koji objekti su automobili i da ispiše njihove modele:
Code:
internal class Program
{
    public static void Main(string[] args)
    {
        var allItems = new List<object>
        {
            new Honda { Model = "Civic" },
            new Porsche { Model = "Porsche 911" },
            new Boeing { Model = "747" }
        };

        DisplayCarModels(allItems);
    }

    private static void DisplayCarModels(IEnumerable<object> items)
    {
        foreach (var item in items)
        {
            if (item is Honda)
                Console.WriteLine(((Honda)item).Model);
            else if (item is Porsche)
                Console.WriteLine(((Porsche)item).Model);
        }
    }
}

Rezultat:
Code:
Civic
Porsche 911

Primetićeš da u metodi DisplayCarModels smo morali da ispitujemo da li je objekat odeređenog tipa i da ga cast-ujemo u taj tip kako bismo dobili vrednost Model property-a. Ovde ne samo da ima malo više za kucanje, već se i narušava open / closed principle koji je jedan od SOLID principa http://en.wikipedia.org/wiki/Solid_(object-oriented_design) (neki ih smatraju i svetim gralom objektno orjentisanog programiranja :) ).
Šta to zapravo znači?
Ako kreiraš novu klasu Ferrari, moraćeš da promeniš i metodu DisplayCarModels koja treba da ispita da li je objekat tipa Ferrari.

Kako da rešimo ovo? Primenom interfejsa :) Honda i Porsche će implementirati interfejs ICar, a Boeing neće.

Definišemo novi interfejs
Code:

public interface ICar
{
    string Model { get; set; }
}

Sklopimo ugovor između klasa i interfejsa
Code:
public class Honda : ICar
{
    public string Model { get; set; }
}

public class Porsche : ICar
{
    public string Model { get; set; }
}

public class Boeing
{
    public string Model { get; set; }
}

Napravimo izmenu u DisplayCarModels metodi.

Code:
internal class Program
{
    public static void Main(string[] args)
    {
        var allItems = new List<object>
        {
            new Honda { Model = "Civic" },
            new Porsche { Model = "Porsche 911" },
            new Boeing { Model = "747" }
        };

        DisplayCarModels(allItems);
    }

    private static void DisplayCarModels(IEnumerable<object> items)
    {
        foreach (var item in items)
        {
            if (item is ICar)
                Console.WriteLine(((ICar)item).Model);
        }
    }
}

Rezultat:
Code:
Civic
Porsche 911


U metodi DisplayCarModels ispitujemo da li objekat ima sklopljen ugovor sa ICar interfejsom jer on sadrži ono što nama treba. Ne zanima nas da li objekat pored modela sadrži još neki propery ili metodu...

Ako dodamo novu klasu Ferrari koja implementira interfejs ICar, metoda DisplayCarModels će raditi bez ikakvih modifikacija:

Code:
internal class Program
{
    public static void Main(string[] args)
    {
        var allItems = new List<object>
        {
            new Honda { Model = "Civic" },
            new Porsche { Model = "Porsche 911" },
            new Boeing { Model = "747" },
            new Ferrari { Model = "Enzo" }
        };

        DisplayCarModels(allItems);
    }

    private static void DisplayCarModels(IEnumerable<object> items)
    {
        foreach (var item in items)
        {
            if (item is ICar)
                Console.WriteLine(((ICar)item).Model);
        }
    }
}

Rezultat:
Code:
Civic
Porsche 911
Enzo


[Ovu poruku je menjao Dejan Carić dana 24.06.2012. u 20:54 GMT+1]
 
Odgovor na temu

darthskywalker
Luka Skajvoker

Član broj: 286923
Poruke: 25
31.176.194.*



+1 Profil

icon Re: C# interface-i - svrha24.06.2012. u 23:15 - pre 144 meseci
Svaka cast na odlicnim primjerima :) hvala puno
 
Odgovor na temu

[es] :: .NET :: C# interface-i - svrha

[ Pregleda: 3194 | Odgovora: 3 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.