Ahoj mam dotaz k rozhraním, něco mi není jasné když vytvařím svou třídu a dědím nějake rohraní už udělané např IComparer která mam metodu int IComparer.Compare(object a, object b), tak na co používám tuto metodu když si ji stejnak musim vymyslet sám?? Neni lepší a jednodušší si napsat svoji vlastni metodu aniž bych dědil nějake rozhraní??
Fórum › .NET
Rozhrani
sksu si precitat tento clanok cast venovanu rozhraniam
http://programujte.com/?akce=clanek&cl=2006061803-kurz-c
To PeterM : ja vim ze rozhrani uvadi jenom prototypy funkci ktere pak musim jak z něj dědit jej překryt ale dejme tomu tento priklad
class Obdelnik : ITvar, IComparable
{
public int delka;
public int vyska;
public Obdelnik(int delkaValue, int vyskaValue)
{
delka = delkaValue;
vyska = vyskaValue;
}
public int Obsah
{
get { return delka * vyska; }
}
public int Obvod
{
get { return (delka+vyska)*2; }
}
public string VratNazevTvaru()
{
return "Obdelník";
}
public int CompareTo(object obj)
{
Obdelnik other = (Obdelnik)obj;
return Obsah.CompareTo(other.Obsah);
}
}
tady musel implementovat CompareTo, ale ted me zajima k čemu to je dobre když ja vubec nemusim používat žádne rozhrani a jenom si napíšu tutež metodu (třeba i s jinym názvem) a bude to fungovat stejně i bez toho rozhrani?? Tak diky za odpovědi
No jestli to bude fungovat... Záleží co s tím budeš chtít dělat. U IComparable předpokládám že řadit :)
Příklad #1:
Budiž tedy program co řadí obdélníky podle obsahu (to už skoro máme ;) ). Budiž List<Obdelnik> s několika instancemi obdélníku.
Jelikož jsem si podctivě vyplnil IComparable, stačí mi teď na na onom Listu zavolat metodu "Sort()" a voila, je seřazeno :)
Pokud mám vlastní implementaci, musím projít celou kolekci a použít třeba quick sort pro řazení podle mé metody. To je hafo psaní navíc, ale v takovémhle příkladě se to ještě dá.
* * * *
Příklad #2
Zatím nuda a rozhraní skutečně netřeba. Uděláme si to trošičku komplikovanější - ale myslím že dobře uvidíš sílu interfacu. Budiž tedy program co řadí obdélníky, čtverce, trojúhelníky, kosočtverce, kosoobdélníky, sudokopytníky a lichokopytníky, hrnce a kastroly, knihy a stromy a domy ( ;) ) podle obsahu.
Pokud si u všech podstivě implementuju IComparable, můžu v klidu řadit všechny najednou.
Vsuvka:
Obdélník jak jsi ho popsal ty, budu tedy muset lehounce přizpůsobit (nepůjde přetypování na "Obdelnik" protože až bude "other" třeba sudokopytník, spadlo by to) ale elegantně si pomůžu jedním interfacem navíc:
public interface IHaveObsah : IComparable{ // Je docela hloupé používat takovejhle česko-anglickej mix jmen, ale příklad.
int Obsah{get;}
// int Obvod{get;}
}
Tenhle interface také implementuji (stačí ho přidat do hlavičky protože už jsme ho vyplnili) a změním řádek
Obdelnik other = (Obdelnik)obj;
na IHaveObsah other = (IHaveObsah)obj;
Konec vsuvky
Nyní tedy budiž List<IHaveObsah> do kteréhu nacpu všechny věci:
List<IHaveObsah> list = new List<IHaveObsah>();
list.Add(new Trojuhelnik(40,30,20));
list.Add(new Trojuhelnik(50,10,20));
list.Add(new Sudokopytník("íhahaaa"));
list.Add(new Dum(VelikostDomu.velký)); // jsou to jen příklady ;)
list.Add(new Ctverec(40,30,20,60));
list.Add(Tree.GetOak());
list.Sort();
První kouzlo: List má jako generikum Interface. Pokud všechny tyto třídy tento interface implementují, můžu do něj všechny tyhle instance v klidu nacpat.
Druhé kouzlo: Protože IHaveObsah rozšiřuje IComparable (dědičnost, klasika...) bude Sort() fungovat. Kdyby jsi chtěl vlastní implementaci (volat nějakou metodu která není kryta žádným interfacem), tak se asi zblázníš, protože jde o strašně moc druhů objektů.
* * * *
Jasná? :)
To splite : no tak dobra ja si vytvařim teda vlastní interface třeba IPorovnavej kde bude metoda (prototyp) int porovnej (object co) bude to pak plnit stejnou funkci jak IComparable nebo IComparable ma neco navic než moje vytvořená interface???diky
Pekne vysvetlene :)
alp: a ja som to pochopil len som to nevedel ako vysvetlit..osobne si myslim, ze interface sa zide skor vtedy ked budes vytvarat viac roznych objektov s ktorymi budes chciet robit to iste ....napr triedit podla objemu ...ked by si to pouzival len na jednu vec pri jednom type objektu to asi velky vyznam nema ...ale este raz vravim je to moj neodborny nazor a kludne sa mozem mylit
To splite : ono mi to ted nejak dochazi ze vlastne List hleda ke trizeni rozhrami IComparable, jinak pouzije vychozi rozhrani?? Jenom by me zajimalo kdyz pouziju nejake jine rozhrani ktere dela neco jineho tak jak poznam ze nejake metoda jak tady u List (sort) toto rozhrani pouzije?? To je asi blba otazka ale jeste to nemam v hlave nejak urovnane
To PeterM : Jop, správně :) To by se dalo označit za "základní použití" -- další třeba je... eee... Komunikace mezi dll, pluginování... Představ si systém na načítání plugin (bezva funkční příklad: http://programujte.com/?akce=clanek&cl=2006041802-C%2523-aplikace-s-podporou-pluginu-c - i když jsem v něm svého času krapet tápal co je ten parametr u CreateInstance() ;) ). Tobě je vlastně jedno co daná plugina bude provádět, potřebuješ jí ale ve správný čas říct "dělej co umíš". Takže si vytvoříš sérii několika interface, šoupneš je do vlastního .dll a všechny pluginy budou importovat jen tuto knihovnu. Core aplikace pak každou jednu pluginu používá jen přes interface - jen přes to, na čem jsi se "domluvil" pomocí interface. Core prostě nemůže tušit co je v každé jedné plugině... Když bude v plugině "mojeUzasnaMetodaKteraHackneInternetDoDesetiSekund(string kdeZacit, string jmenoPritelkyne)" tak je ti to úplně na nic, protože core nemá křišťálovou kouli aby zjistilo že jí má někdy zavolat.
Nebo, jiný příklad, představ si že plugina potřebuje přístup k databázi. Tak jednoduše implementuje rozhraní "IWantDB" kde je definice nějaké vlastnosti "IDb Database{set;}" - Core pak zkusí každou jednu pluginu přetypovat na tohle rozhraní a jestli se to povede (nevyhodí to vyjímku, try catch, klasika...) tak použije metodu "_instancePluginy.Database = xxx" - a plugina dostane co potřebuje.
Tyhle interface použité v pluginách musí být samozřejmě předem domluvené - volání metod z nich je natvrdo nakódované v core a žádná plugina je z logiky věci nemůže změnit. Respektive teda může (přepíše natvrdo celé .dll s interfacema) ale core bude volat stejně jen ty metody z těch interface které zná (a nebo celá aplikace spadne, pokud nějakou umazal a ty jí, neexistující zavoláš - při kompilaci by to neprošlo, ale stačí kdyby někdo prostě zkompiloval .dll zvlášť a jen přepsal soubor. To je už takovej extrémní případ a na 99% jde o zpackanej a dost ubohej (nebo naprosto geniální :) ) pokus o hack nebo čiré amatérství), prostě jen ty které jsi v něm ty sám někde v kódu nadatlil.
To alp : Přesně tak. Až na to "výchozí rozhraní" - nic takového neexistuje, "object" nic neimplementuje :) Prostě to spadne na pokusu o přetypování na rozhraní. To s tím Sort() je jen příklad, v frameworku je milion dalších použití. A v příkladě pro PeterM, s pluginama, to vlastně ani jinak nejde, než komunikovat přes interface. A miliony dalších věcí které mě zrovna teď nemůžou napadnout :)
"Hledá" je možná moc nadvznesený výraz, prostě to zkusí přetypovat (object x, y; try{((IComparable)x).CompareTo(y);} catch {throw new Exception("Je třeba implementovat IComparable!");} -- a je dost možné že se ani s tím přepsáním Exception na srozumitelnější nezdržuje :) ) a hotovo.
Interface je vlastně takové "hele, kámo, je mi totálně jedno co nebo čeho jsi za instanci, tady máš seznam věcí které po tobě můžu chtít". V příkladě nahoře, IComparable, jde o .net frameworkem předdefinovaný interface který říká konkrétně o "Hele, když ti řeknu 'object Á' tak buď schopnej mi říct zda jsi větší, stejný nebo roven, jo?" - a tuhle větu použije třeba zrovna metoda "Sort()" u Listu. Ale prakticky může jít o cokoliv, nejen pro porovnávání. Třeba "Hele kámo, chceš se nějak vykreslit? Tak si udělej metodu 'Draw(GraphicContext gr);' a až budu potřebovat kreslit tak se ti přes ní ozvu." Et cetera et cetera...
BTW: Autor tohoto příspěvku před napsáním přišel z hospy, kde měl tři pivka s kámošema. Snad píše srozumitelně :)
BTW2 a edit: Slovíčkaření... Interface se "implementuje", dědičné věci (abstraktní třídy, Form ( :) ) atd) se "rozšiřují". V javě se to musí psát "implements / extends", v c# se píše jen dvojtečka, což někdy může být matoucí (na první pohled nepoznáš jestli kolega rozšiřoval nebo implementoval), proto je také dobré začínat jméno interface písmenem velké i - "I". Někdy jsou výsledná jména kouzelná, viz třeba to "IWantDB - Já chci DB" :)
To splite : No pekne uz rozumiem ...este otazka ...dajme tomu zeby Interface mal 3 metody ale pri implemetnacii by som v triede ktora ho implementuje prepisal len dajme tomu 2 ..skonci to chybou? ci staci prepisat len metodu ktoru potrebujem.
To PeterM : Zkus, uvidíš.
Jestli jsi jako já línej pouštět Visualko, tak... To neprojde při kompilaci. Bude ti to říkat že některé položky interface nejsou vyplněny a app se prostě nezkompiluje. Je to logické, protože když už jsi implementoval interface, může přes něj k tobě kdokoliv přistupovat. Takže je to vlastně to samé, jako by jsi napsal this.MetodaKteraNeexistuje() - taky ti to neprojde :)
To alp : np :)
Hezký den :)
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
C# - rozhrani a vlastnosti — založil jirkab
Grafické rozhraní — založil ninja řízek
Uživatelské rozhraní v C++ — založil LPG1995
Abstraktní metody a rozhrání — založil ViliX64
Moderátoři diskuze