Diskuze: Společný předek v listu a Interface

C# .NET .NET (C# a Visual Basic) Společný předek v listu a Interface American English version English version

Avatar
Petr Nymsa
Redaktor
Avatar
Petr Nymsa:

Opět mám dotaz. Je lepší držet si pozice herních objektů (zdi, barely, dveře) v jedné kolekci se společným předkem nebo například kvůli dveřím si vytvořit druhou kolekci objektů Doors který má spoelčného předka GameObjects ? Občas prostě narážím na malé zkušenosti s pěkným návrhem a už teď pocitúju že návrh není úplně nejlepší (ale to zacházím).

Dále se chci zeptat na Interface. Stále nemůžu přijít na správné využití Interfaců, mohl by někdo napsat nějaký pěkný příklad ? :) Zatím vidím výhodu v tom, že když chci "dědit" od více tříd, kdy prostě potřebuju z obou tříd něco převzít, tak to udělám jako Interface.

Díky moc za odpovědi :)

PS.: Časem možná přibude dotaz na tvorbu světla v XNA. Zatím mi funguje celkem pěkně, ale není to "to pravé" světlo :)

Odpovědět 15.5.2013 17:55
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Nymsa
David Čápka:

Určitě s jedním předkem. Již jsem někde psal, že interface není nutný a u menších projektů kde je pár tříd bohatě stačí společní předci. Jinak jsem tu o něm napsal docela dost i s tím, k čemu se používá.

Editováno 21.5.2013 9:27
Nahoru Odpovědět 21.5.2013 9:27
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Petr Nymsa
Kit:

Pokud ti nějaká továrna vyrobí objekt neznámého typu a v tom generovaném objektu chceš zavolat nějakou metodu, musí ta metoda být deklarována v interface. Jinak ti překladač bude tvrdit, že objekt takovou metodu nemá.

Všechny třídy, které jsou v té továrně, musí toto interface implementovat.

Nahoru Odpovědět 21.5.2013 9:39
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Ono si to jde jednoduše představit u her na interfacy typu IPohyblivy, IHorlavy, IJidlo a podobně. Mám na to připravenou takovou ukázku, ale v nejbližší době to sem dát nestihnu.

Nahoru Odpovědět 21.5.2013 9:56
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Nějak jsem si nezvykl psát "I" na začátku jména interface. Vždyť ani rozhraní, které jsou součástí jazyka, tam to "I" nemají.

Nahoru Odpovědět 21.5.2013 10:05
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

V Javě ne a je to chyba, protože se na první pohled nepozná, jestli to je třída nebo Interface. Proto C# tuto konvenci zavedl a používá ji u všech interfaců.

Nahoru Odpovědět 21.5.2013 10:07
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Takže bych to vlastně měl psát nějak takto:

IKolekce<int> prvocisla = new List<int>();

Interface IKolekce jsem si vymyslel, ale snad je jasné, co tím chci sdělit.

Nějak nevidím důvod, proč bych měl rozlišovat mezi třídou a interface.

Editováno 21.5.2013 10:23
Nahoru Odpovědět 21.5.2013 10:21
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Petr Nymsa
Luboš Běhounek (Satik):

Vytvářet si druhou kolekci už jen určitých herních objektů se vyplatí ve chvíli, kdy těch objektů je hodně a potřebuješ urychlit jejich procházení, hlavně pokud je to (procházení celé kolekce)², tam je znát, jestli je to cyklus 10x10 nebo 1000x1000 - třeba když testuješ kolize určitých objektů mezi sebou.

Asi nejběžnější a nejlepší na pochopení použití interfaců je ISerializable - potom u všech objektů, které ho implementují máš funkci, která ti ten objekt převede na pole bajtů a zpět.

Případně třeba INetworkable - podobné, ale nemusíš vždy posílat všechny bajty objektu, ale jen určité, které jsou pro danou zprávu potřeba.

IDisposable - pro objekty, které při zanikání potřebují uvolnit systémové prostředky - třeba zavření connection do databáze, vymazání textury z paměti grafické karty, zavření souboru apod.

Interface se prostě používají kdykoliv potřebuješ nějakou stejnou funkcionalitu od tříd, které si jinak nejsou vůbec příbuzné.

Nahoru Odpovědět 21.5.2013 10:28
:)
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

Uh, to je divné použití, kolekce interfacu by byla takhle:

List<ISerializable> seznam = new List<ISerializable>();

Ale David Čápka myslel spíš asi hlavičku třídy

class Trida : IDisposable, ISerializable, Predek
{

}
Nahoru Odpovědět 21.5.2013 10:33
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

To jsem střelil od pasu. V tu chvíli mě nenapadlo nic vhodnějšího. V Javě však běžně píšu

List<int> prvocisla = new ArrayList<int>();

nebo dokonce

Collection<int> prvocisla = new ArrayList<int>();

kde List a Collection jsou interface a ArrayList implementace.

Nahoru Odpovědět 21.5.2013 10:41
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Luboš Běhounek (Satik)
Luboš Běhounek (Satik):

Tak asi nemyslel hlavicku, ale kod, koukam, ze Java rozlisuje predka a interface v hlavicce tridy pomoci slovicek extends a implements.

treba

Vysledek result = ... prirazeni odnekud

kde bys nepoznal, jestli Vysledek je trida nebo interface.

Nahoru Odpovědět 21.5.2013 10:41
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

A proč je důležité rozlišit, jestli Vysledek je třída nebo interface?

Nahoru Odpovědět 21.5.2013 10:44
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

Aha, takhle jsi to myslel, kolekci, ktera je zaroven interface.

Zrovna u tohohle pouziti to tak nevadi, vice je to zrejme kdyz mas kolekci interfaců.

List<int> prvocisla = new ArrayList<int>();

Tohle pouziti nijak nevadi, ale zacne prekazet kdyz budes chtit pouzivat pokrocilejsi funkce ArrayListu, ktere rozhrani List neobsahuje a pridava je az implementace ArrayList - pak budes muset pretapovavat, aby ses k nim dostal (samozrejme pokud v danou chvili vyuzivas jen zakladni funkce, pak to potreba ani nebude).

Nahoru Odpovědět 21.5.2013 10:49
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

Přesně tak. V Javě je List pouze interface, nedají se z něho dělat instance. Má se používat co nejnižší interface, které ještě splní naše požadavky, klidně to může být i Object, pokud potřebuji jen metodu toString. Případně Numeric u čísel.

Nahoru Odpovědět 21.5.2013 10:56
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

Třeba proto, že třída a interface je úplně něco jiného. Proto by se to mělo i jinak jmenovat. V Javě je třeba List velmi špatně zvolený název pro rozhraní, tak by se měla jmenovat kolekce.

Nahoru Odpovědět 21.5.2013 11:02
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Petr Nymsa
Redaktor
Avatar
Petr Nymsa:

Díky všem za odpovědi :). Teď jsem došel do bodu, kdy jsem zjistil že to mám mírně špatně navržený ;( Sice to můžu nějak doplácat, ale to nechci, časem to bude ještě horší. Nezbývá nic jiného než to trochu přepsat. Nastíním problém, možná mi řeknete tip co a jak. Prostě ještě v tomhle trochu víc plavu a občas si to nedovedu představit i několik kroků dopředu aby to bylo furt nějak dobře použitelný. Takže dělám hru, 2D hra z ptačí perspektivy, je to spíše test "enginu" takže kolize,kamera, světlo, generování mapy ... popíšu základní třídy které mám. Zatím nepoužívám Interface a právě ho budu asi muset použít abych to líp oddělil. Spíše to přepíšu tak nějak hodně :D...

Abstraktní třída HitableObject
Obsahuje pouze Rectangle - určuje pozici, kolizi
Obsahuje jedinou metodu - CheckCollision - kontrola kolize

Tuto třídu používám například pro UserComponenty - Button,TextBox...

Třída GameObject : HitableObject
Rozšiřuje HitableObject o Texturu a dvě metody Update a Draw. Třída je abstraktní.
Přidává vlastnost Solid - určuje, jestli může hráč, střela,... projít objektem nebo ne.

Pracuju na světle. Světlo funguje tak že mění vlastnosti objektů - Visibility a to na tři stavy: Visible,Explo­red,NoVisible.

Visible způsobí plnou viditelnost objektu
Explored značí, že jsme už tady byli ale nejsme poblíž, objekt je ztmaven ale je mírně vidět.
NoVisible - objekt není vidět. Je tam tma.

No předpokládám že by bylo na místě udělat si interface ILightableObject, který by implementoval enum Visibility a metodu která změní stav.
Poté si tedy vytvořím třídu jako MapObject (objekt který bude ovlivňován světlem a je na mapě), která bude dědit od GameObject a bude implementovat rozhraní ILightableObject.

Poté si tyto všechny objekty naházím ještě do nějaké společnější třídy Map, která bude držet info o mapě a vždy proiteruju všechny objekty ILightableObject a nastavím jim změnu viditelnosti

Je tento nápad správný ? Díky :)

Nahoru Odpovědět 21.5.2013 14:56
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Rozdíl mezi třídou a interface je v podstatě jen v tom, že třída navíc obsahuje i implementaci.

Nahoru Odpovědět 21.5.2013 14:59
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Jakub Šárník:

U kolika tříd bys chtěl implementovat ILightableObject?

 
Nahoru Odpovědět 21.5.2013 16:03
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na Jakub Šárník
Petr Nymsa:

No třídy, které představují mapu - zdi, podlaha ... dále samozřejmě na různé objekty jako jsou truhla, sudy a nakonec nepřátele a interaktivnější objekty.

Nahoru Odpovědět 21.5.2013 16:20
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

Interface nemůže obsahovat žádná pole, jen tím říkáš, jaké funkce/vlastnosti musí objekt mít.

Nahoru Odpovědět 21.5.2013 16:53
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

Vylučuje se to snad s tím, co jsem napsal? Datová pole jsou součástí implementace.

Nahoru Odpovědět 21.5.2013 16:56
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Nymsa
David Čápka:

U her se většinou generalizuje, příklady že máš třídu Truhla jsou jen z učebnic objektově orientovaného programování. Co konkrétně děláš?

Nahoru Odpovědět 21.5.2013 17:08
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:

No právě, dokud se nepodívá do zdrojáku, tak netuším, jestli je List třída nebo Interface. Když jsou tam názvy končící -able a podobně, tak se to ještě dá, ale interface List mi přijde velmi zavádějící a jediná možnost jak kód pochopit je lovit v manuálu.

Nahoru Odpovědět 21.5.2013 17:10
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

Nevylučuje, jen to doplňuju :)

Nahoru Odpovědět  +1 21.5.2013 17:15
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Ale pořád mi z toho nedochází, proč bych měl vědět, zda je List třída nebo interface. Použití je skoro stejné. Dokonce z interface mohu klidně udělat instanci anonymní třídy úplně stejně jako ze standardní třídy.

Proto si myslím, že je v principu zbytečné ty názvy rozlišovat nějakým "I" na začátku názvu. Je to jen nějaká konvence specifická pro C#, PHP a možná pár dalších jazyků, ale Java ji nepotřebuje.

Editováno 21.5.2013 17:26
Nahoru Odpovědět 21.5.2013 17:24
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

Hodi se to vedet - treba tohle udelat (v C#) nemuzes:

ISerializable data = new ISerializable();

Bez toho rozdilneho pojmenovani to nepoznas, musis se divat do manualu.

Ale uz muzes samozrejme udelat:

ISerializable data = new TridaImplementujiciISerializable();

(to jsi tu popisoval)

Jak je to u jinych jazyku nevim, ale treba v C# nemuzes vytvorit instanci interfacu.

Editováno 21.5.2013 17:37
Nahoru Odpovědět 21.5.2013 17:37
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

V Javě můžeš instanci z interface vytvořit například takto:

interface Command {
    void execute();
}

public class Comm {
    public static void main(String[] args) {
        Command hello = new Command() {
            public void execute() {
                System.out.print("Hello ");
            }
        };
        Command world = new Command() {
            public void execute() {
                System.out.print("World! ");
            }
        };
        hello.execute();
        world.execute();
    }
}

Dokonce v tomto případě interface může být i uvnitř třídy Comm.

Editováno 21.5.2013 17:51
Nahoru Odpovědět 21.5.2013 17:49
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na David Čápka
Petr Nymsa:

Tak jasně že nebudu mít třídu Truhla ale spíše třídu, která bude rozšířená o to že bude dělat větší interakci s hráčem. Otevře se, nabíde svůj seznam položek, které vlastní apod.

Co přesně dělám ? Je to závěreční práce z programování 2.ročníku. Je to hlavně spíše návrh trochu "univarzálnějšího enginu", tedy snažím se to psát tak aby se to dalo alepoň zčásti použít i jinde.

Ten test (hra) bude vlastně 2D hra z ptačí perspektivy, kde budeš chodit náhodně vygenerovaným bludištěm s místnostimi, hledat poklady a sem tam porazíš potvoru.

Hlavně zde zkouším kameru, světl. Časem chci zkusit různé efekty, implementovat nějakou pěknou AI, prostě vytvořit něco co bude ukázkou jak to všechno pracuje. Uvidím jak to vše budu stíhat. Učiteli bude stačit když se budu moct procházet, střílet a aby tam byla nějaká lehčí AI. Světlo je navíc a ono vlastně funguje, jenom je to prostě špatně navržené a trochu se to zkomplikovalo. Proto jsem si řekl, že to opravím dřív než později.

Nahoru Odpovědět 21.5.2013 17:54
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Nymsa
David Čápka:

Byla by tam nějaká třída Kontejner, která by měla vlastnosti jako název, sprite a podobně. Hráč by její instanci jednou viděl jako truhlu, jednou jako popelnici a podobně. Rozhraní má smysl v případě, když bys tam chtěl třeba objekt, co je zároveň jako kontejner a zároveň jako vozidlo (třeba auto má kufr pro přepravu věcí a jde s ním i jezdit), potom by třída auto implementovala rozhraní IVozidlo i IKontejner. Výhoda rozhraní je, že uděláš jednou práci s kontejnerem a pak ti je šumák jestli je to krabička od zápalek nebo náklaďák, vidíš jen tu část objektu, kterou v danou chvíli potřebuješ.

Nahoru Odpovědět 21.5.2013 18:14
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

Hm, zajimave, ani netusim, jestli v c# neco podobneho jde, ale v podstate je to jen anonymni trida implementujici to rozhrani, takze to neni doopravdy instance rozhrani, ne?

Nahoru Odpovědět 21.5.2013 18:15
:)
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na David Čápka
Petr Nymsa:

Však tak to myslím :) A s tím rozhraním. Asi ho tedy použiju pro to světlo. Všechny objekty , které mohou být osvětlené budou implementovat to rozhraní a tím krásně nastavím světla. No trochu to přepíšu a budu psát dál. Už vím že teď to nebudu extra dobrý :). Každopádně až to sepíšu, pošlu sem komplet kód a budu strašně rád, když se na to někdo z vás mrkne a řekne co je dobrý, co je špatný. Co udělat líp apod.

Já sice chápu výhodu rozhraní ale stále nevím jak ho správně používat. Dokud asi neuvidím nějaký složitější příklad, nepochopím to úplně dobře :(

Nahoru Odpovědět 21.5.2013 18:19
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Nymsa
David Čápka:

Jinak koukám, že jsi asi jediný, co dělá na tom "společném projektu" :D

Nahoru Odpovědět 21.5.2013 18:19
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na David Čápka
Petr Nymsa:

No ten "společný projekt" se totálně rozpadl. A stále mám v hlavě svůj nápad. Teď dělám tedy na Alpha v0.000005, která bude mít základy a poslouží i jako závěrečná práce.

Měli jsem 2 schůzky na Skypu, přišel jsem já, Michael Olšavský a Satik. Jeden Anonym měl pravdu, neumíme se domluvit, organizovat. Nebo aspoň já nedokážu asi (zatím) úplně organizovat skupinu lidí napříč republiky :D

Nahoru Odpovědět 21.5.2013 18:22
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

Ano, je to vytvoření instance anonymní třídy. Úplně to samé však můžeš udělat s každou nefinální třídou.

Nahoru Odpovědět 21.5.2013 19:50
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

Ber to tak, že standardní třída má kromě interface ještě navíc implementaci. Můžeš ji překrýt, ale u interface ji překrýt musíš. Třída, abstraktní třída a interface mají společné vlastnosti. Je tedy možné je rozlišit "I" na začátku, ale nutné to není.

Nahoru Odpovědět 21.5.2013 20:00
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Odpovídá na Kit
Luboš Běhounek (Satik):

David Čápka nemel na mysli nazvy vlastnosti zacinajici na I, ale primo nazev rozhrani zacinajici na I.
U vlastnosti to nema smysl pojmenovavat jinak, protoze to preci kazda trida uz nejak implementuje.

Nahoru Odpovědět 21.5.2013 20:18
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

Neměl jsem na mysli "vlastnosti", ale společnou podmnožinu použitelnosti. Kruci, jak jinak napsat slovo vlastnosti, aby to nebyly gettery a settery.

Nahoru Odpovědět 21.5.2013 22:11
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 37 zpráv z 37.