Kezdőoldal » Számítástechnika » Programozás » Mikor és mivel jobb interface-...

Mikor és mivel jobb interface-ből példányosítani? [C#][OOP]

Figyelt kérdés

Tehát van egy interfacem

interface IKiir{

void Kiir();

}


class Pelda : IKiir{

void Kiir(){Console.WriteLine("Pelda");}

}



Példányosítás:


IKiir _kiir = new Pelda();


vagy


Pelda _pelda = new Pelda();



Melyik formula, mikor jó és miért jó? Sok helyen azt látom, hogy Interfaceből példányosítanak. Miért van ez?


2020. okt. 12. 12:21
 1/5 anonim ***** válasza:
55%
Akkor szokás interfész típusú objektumot létrehozni, ha garantálni akarjuk, hogy az őt használó kód biztosan megtalálja a szükséges metódusokat. Például ha csinálsz egy keretrendszert, ami objektumokkal dolgozik, akkor kikötheted, hogy csak az általad megadott interfész osztályú objektumok adhatók hozzá.
2020. okt. 12. 13:02
Hasznos számodra ez a válasz?
 2/5 anonim ***** válasza:
55%

Én azért helyesbítek: Nem interfész objektumot hozunk létre, és nem interfészt példányosítunk, hanem a megfelelő osuztált példányosítjuk, és az utána kasztolódik interfész-objektummá.

Elsődlegesen heterogén kollekcióban lehet érdemes használni, ha olyan funkcionalitást akarunk használni belőle, ami mindegyikben implementálva kell legyen.

Egy példa. IGurul interfészt hozunk létre, és vannak osztályaink, mint Bicikli, Auto, Vonat. Ezek különbözőképpen mozognak, azonban közös bennük, hogy van mozog() függvényük. (Sok esetben persze érdemesebb leszármazni egy Jarmu osztályból, de csak egyszeres öröklés lehetséges c#-ban, így ha másból is akarunk leszármazni, akkor interfész kell)

Ekkor Listában eltárolhatjuk például így:

List<IGurul> gurulo_dolgok;

És ha for ciklussal végigmegyünk, akkor

for(var v in gurulo_dolgok){

v.gurul();

}

És akkor mindegy nekünk, hogy amúgy mit tud még, vagy hogyan csinálja, csak az a fontos, hogy mindegyiknek van gurul függvénye, amiben bármit csinálhat, akár egy kutya ugathat is, nem kell (de ajánlott) reprezentálnia a valós működést.

2020. okt. 12. 13:11
Hasznos számodra ez a válasz?
 3/5 anonim ***** válasza:
55%

Vannak olyan rendszerek (pl. a Java-ban a Spring) ami konfigurációt kód szinten is belehet állítani. Ez esetben mivel több implementációja is lehet egy adott funkciónak, így interface-t kér, hogy erre implementáld le amit szeretnél. Ezzel szabad kezet ad, hogy hogyan valósítod meg más-más funkciót egy adott interfészre.


De kimondottan akkor szoktam interfészt létrehozni, és most korrekt példával jövök, mert erre pont kellet ilyen:

- Van egy Cassandra adatbázis modellem (olyan mint az ORM model)

- és van egy Redis adatbázis modellem

Mivel ezek nem kompatibilisek egymással, de az egyik csak memóriában gyórsító tárazza a Cassandra adatát. Tehát közel azonosak az adatok. Így mind2 rendelkezik azzal ami nekem kell. Szóval csináltam rá egy interfészt, ami visszadja a számomra fontos információt.

Ezek után, most hogy Cassandra modeljét adom át vagy a Redis modeljét, mivel mindkettőben benne van azok a metódusok amiket az interfész megkövetel, így nincs problémám vele, hogy melyiket adom át. A hívandó metódusban, meg már számomra lényegtelen mi jött át, csak a metódusokat érjem el. :)

2020. okt. 12. 14:09
Hasznos számodra ez a válasz?
 4/5 anonim ***** válasza:
0%

IKiir _kiir = new Pelda();

Pelda _pelda = new Pelda();


Ha ez így szerepel, akkor a kettő közül mindig a másodikat használd. Az első változat egy rossz megoldás, ugyanis a '_kiir' változó statikus típusa miatt elveszted azokat az információkat (függvények, propertyk, stb), amik csak a 'Pelda' típuson vannak rajta.


Olyat láthatsz gyakran, hogy egy függvény paramétere az interface. Ilyen esetekben egy öröklési hierarchiánál célszerű azt a legmagasabb szinten lévőt választani (tehát amelyiknek a legkevesebb őse van), amelyikkel az adott függvény vagy osztály még működni képes. Így több helyen és módon fogod tudni felhasználni az osztályodat / függvényedet, és jobb lesz a kód bővíthetősége.

2020. okt. 12. 18:08
Hasznos számodra ez a válasz?
 5/5 anonim ***** válasza:
53%

Konyhanyelven fogalmazva az interfész azt írja le, hogy hogyan kell valamilyen szolgáltatást nyújtani, illetve hogyan lehet egy adott szolgáltatást igénybe venni.


Vegyünk egy egyszerű (és egyben lesarkított) példát. A mikrohullámú sütőnek áram kell, hogy működjön. Honnan lehet áramod? Előállíthatja azt egy aggregátor, egy atomerőmű, napelem, stb.


Így első nekifutásra ez egy teljesen rendben lévő kódnak tűnik:

class Áram {...}

class Kaja {...}


class Aggregátor {

.. public Áram GetÁram() {...}

}


class Mikró {

.. public void Melegít(Kaja k, Aggregátor áramforrás) {...}

}


Aggregátor aggregátor = new Aggregátor();

Mikró m = new Mikró();

m.Melegít(new Kaja(), aggregátor);


Teljesen oké, működik a mikró. Mi van akkor, ha nekem nem aggregátorom van, hanem mondjuk napelemem?


class Napelem {

.. public Áram GetÁram();

}


Napelem napelem = new Napelem();

Mikró m = new Mikró();

m.Melegít(new Kaja(), napelem);


Na de állj... Miért nem működik ez?! A mikrónk konkrétan csak aggregátor által előállított árammal hajlandó működni? Hát, itt valamit elrontottunk...


Elvileg mindegy kellene lennie, hogy honnan van áramom, nem? Amíg van valamim, ami áramot ad, addig a mikrónak mennie kellene... Tehát a mikrónknak nem aggregátorra van szüksége, hanem valamire, ami áramot ad neki. És itt jön a képbe az interfész:


interface IÁramforrás {

.. Áram GetÁram();

}


//Van két osztályom, ami az IÁramforrás által előírt dolgokat szolgáltatja (áramot ad)

class Aggregátor : IÁramforrás {...}

class Napelem : IÁramforrás {...}


//És van a mikróm, ami azt a szolgáltatást igénybe veszi (tehát nem konkrét megvalósítástól függ, hanem egy szolgáltatás kell neki)

class Mikró {

.. public void Melegít(Kaja k, IÁramforrás áramforrás) {...}

}


Innentől kezdve a mikrómnak már tökmindegy, honnan van áram:

Aggregátor aggregátor = new Aggregátor();

Napelem napelem = new Napelem();

Mikró m = new Mikró();

m.Melegít(new Kaja(), napelem);

m.Melegít(new Kaja(), aggregátor);


Nyilván ez bagatel példa volt, és a programozás világában ettől vannak absztraktabb élethelyzetek is. De vegyünk például egy olyan esetet, hogy regisztrálsz egy oldalra, és kiválaszthatod, hogy e-mailben vagy SMS-ben kérsz kódot a fiókod megerősítéséhez. Az kinézhet mondjuk így:


interface IVerificationCodeSenderService {

.. void SendVerificationCode(string code, string address);

}


class SmsVerificationCodeSenderService : IVerificationCodeSenderService {...}

class EmailVerificationCodeSenderService : IVerificationCodeSenderService {...}


class UserRegistrationService {

.. private readonly IVerificationCodeSenderService _codeSenderService;

.. public UserRegistrationService(IVerificationCodeSenderService codeSender) {

.. .. _codeSenderService = codeSender;

.. }

.. public void Register(string user_address) {

.. .. //...

.. .. _codeSenderService.SendVerificationCode("test", user_address);

.. .. //...

.. }

}


Ha megfigyeled, a UserRegistrationService-ben egy sort sem kell átírnom, ha e-mailről át akarok térni mondjuk SMS-re, vagy netán egy teljesen új módszert akarok bevezetni, ami eddig nem volt.


Vagy egy másik példa lehet az, hogy valamilyen adatot el kell menteni. Ott is mindegy, hogy fájlba mented, hálózaton küldöd át, feltöltöd Google Drive-ba, Bluetooth-on küldöd el telefonra...

2020. okt. 12. 22:21
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:





Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!