abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
eParkomat, startup z ČR, postoupil mezi finalisty evropského akcelerátoru ChallengeUp!
Robot na pivo mu otevřel dveře k opravdovému byznysu
Internet věcí: Propojený svět? Už se to blíží...
včera 17:02 | Pozvánky

Přijďte si popovídat o open source obecně a openSUSE konkrétně s dalšími uživateli a vývojáři. Oslava nového vydání openSUSE Leap se uskuteční 16. prosince od 17:00 v nových prostorách firmy SUSE v Praze. K dispozici bude nějaké občerstvení a DVD pro ty, kdo je sbírají nebo ještě mají mechaniku. Po párty v kanceláři se bude pokračovat v některé z hospod v okolí.

Miška | Komentářů: 7
včera 14:55 | Zajímavý software

Byla vydána verze Alpha 1.0 otevřeného operačního systému pro chytré hodinky AsteroidOS. Podporovány jsou hodinky LG G Watch, LG G Watch Urbane, Asus ZenWatch 2 a Sony Smartwatch 3. Ukázka ovládání hodinek na YouTube. Jaroslav Řezník přednášel o AsteroidOS na chytrých hodinkách (videozáznam) na letošní konferenci OpenAlt.

Ladislav Hagara | Komentářů: 0
včera 13:30 | Zajímavý software

Byly uvolněny zdrojové kódy známé rogue-like hry DoomRL. Počátky hry jsou v roce 2002. Je napsána ve FreePascalu a zdrojový kód je nyní k dispozici na GitHubu pod licencí GNU GPL 2.0. Autor pracuje na nové hře Jupiter Hell, která je moderním nástupcem DoomRL a na jejíž vývoj shání peníze prostřednictvím Kickstarteru.

Blaazen | Komentářů: 0
včera 13:15 | Pozvánky

Přijďte s námi oslavit vydání Fedory 25. Na programu budou přednášky o novinkách, diskuse, neřízený networking atd. Release Party se bude konat 16. prosince v prostorách společnosti Etnetera. Na party budou volně k dispozici také propagační materiály, nová DVD s Fedorou 25 a samozřejmě občerstvení. Přednášky budou probíhat v češtině. Pro více informací se můžete podívat na web MojeFedora.cz. Jen připomínám, že tentokrát jsme zavedli

… více »
frantisekz | Komentářů: 0
9.12. 16:38 | Komunita

Byly zveřejněny videozáznamy přednášek a workshopů z letošní konference OpenAlt konané 5. a 6. listopadu v Brně. K videozáznamům lze přistupovat ze stránky na SuperLectures nebo přes program konference, detaily o vybrané přednášce nebo workshopu a dále kliknutím na ikonku filmového pásu. Celkově bylo zpracováno 65 hodin z 89 přednášek a workshopů.

Ladislav Hagara | Komentářů: 0
9.12. 11:30 | Komunita

Bylo oznámeno, že bude proveden bezpečnostní audit zdrojových kódů open source softwaru pro implementaci virtuálních privátních sítí OpenVPN. Audit provede Matthew D. Green (blog), uznávaný kryptolog a profesor na Univerzitě Johnse Hopkinse. Auditována bude verze 2.4 (aktuálně RC 1, stabilní verze je 2.3.14). Audit bude financován společností Private Internet Access [reddit].

Ladislav Hagara | Komentářů: 4
9.12. 06:00 | Komunita

Na YouTube byl publikován Blender Institute Reel 2016, ani ne dvouminutový sestřih z filmů, které vznikly za posledních 10 let díky Blender Institutu. V institutu aktuálně pracují na novém filmu Agent 327. Dění kolem filmu lze sledovat na Blender Cloudu. Videoukázka Agenta 327 z června letošního roku na YouTube.

Ladislav Hagara | Komentářů: 0
9.12. 01:02 | Zajímavý článek

Minulý týden byly vydány verze 1.2.3 a 1.1.7 webového poštovního klienta Roundcube. V oznámení o vydání bylo zmíněno řešení bezpečnostního problému nalezeného společností RIPS a souvisejícího s voláním funkce mail() v PHP. Tento týden byly zveřejněny podrobnosti. Útočník mohl pomocí speciálně připraveného emailu spustit na serveru libovolný příkaz. Stejně, jak je popsáno v článku Exploit PHP’s mail() to get remote code execution z roku 2014.

Ladislav Hagara | Komentářů: 1
8.12. 16:00 | Nová verze

Byla vydána verze 0.98 svobodného nelineárního video editoru Pitivi. Z novinek lze zmínit například přizpůsobitelné klávesové zkratky. Videoukázka práce s nejnovější verzí Pitivi na YouTube.

Ladislav Hagara | Komentářů: 1
8.12. 15:00 | Zajímavý software

Stop motion je technika animace, při níž je reálný objekt mezi jednotlivými snímky ručně upravován a posouván o malé úseky, tak aby po spojení vyvolala animace dojem spojitosti. Jaký software lze pro stop motion použít na Linuxu? Článek na OMG! Ubuntu! představuje Heron Animation. Ten bohužel podporuje pouze webové kamery. Podpora digitálních zrcadlovek je začleněna například v programu qStopMotion.

Ladislav Hagara | Komentářů: 5
Kolik máte dat ve svém domovském adresáři na svém primárním osobním počítači?
 (32%)
 (23%)
 (29%)
 (7%)
 (5%)
 (3%)
Celkem 810 hlasů
 Komentářů: 50, poslední 29.11. 15:50
Rozcestník
Reklama

Dotaz: Základy dědění v Javě - začátečník

4.5. 17:10 Fatboy
Základy dědění v Javě - začátečník
Přečteno: 985×
Snažím se pochopit, jak funguje dědění v Javě a ve studijních materiálech mám uvedeno:

"Rodičovský podobjekt nemůže poslat překrytelnou zprávu sám sobě. Jakoukoliv překrytelnou zprávu totiž musí poslat znovu „nejvnějšnější“ instanci, v jejíchž útrobách se nachází (dceři, vnučce, pravnučce–prostě té, která už není ničím rodičovským podobjektem)."

Mohl byste mi to prosím někdo osvětlit na nějakém jednoduchém příkladu?

Řešení dotazu:


Odpovědi

4.5. 19:53 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Proboha, co je to za studijní materiály? Pokud se chcete Javu naučit, doporučuju Učebnici jazyka Java od Pavla Herouta. Akorát se tam teda nedočtete termíny jako „rodičovský podobjekt“ nebo „překrytelná zpráva“, protože v Javě se takové termíny nepoužívají.

Navíc ten úryvek je nejenom zmatený, ale hlavně je úplně špatně, protože v Javě funguje dědičnost mezi třídami, ne mezi objekty/instancemi.

Autor se tím textem pravděpodobně pokoušel vysvětlit, že když máte ve třídě nějakou metodu, která může být překryta (override), při volání té metody se zavolá vždy ta metoda, která je na konci překrývání – metoda, která je implementována v potomkovi. A to bez ohledu na to, že tu metodu voláte z metody předka.
class Zvíře {

  public void hlas() {
    System.out.println("Co to?");
  }

  public void hlasDvakrat() {
    this.hlas();
    this.hlas();
  }
}


class Pes extends Zvíře {

  @Override
  public void hlas() {
    System.out.println("Haf!");
  }
}


class Pudl extends Pes {

  @Override
  public void hlas() {
    System.out.println("Hif hif");
  }

}

Zvíře zvíře = new Pudl();
zvíře.hlasDvakrat();
//vypíše 2× "Hif hif"
Mohl byste si myslet, že zvíře.hlasDvakrat(), která je definovaná ve třídě Zvíře, bude volat metodu hlas() ze „své“ třídy, ale tak to není – voláte metodu hlas() na instanci třídy Pudl, takže se zavolá metoda, která je v hierarchii tříd nejbližší Pudlovi (postupuje se jen směrem k rodičům) – a to je metoda přímo ve třídě Pudl. Kdyby ve třídě Pudl nebyla ta metoda překrytá, postupuje se výš a najde se ve třídě Pes. Kdybyste tam nevytvořil instanci Pudla, ale Psa, začne se od něj a metoda se najde tam, takže by to vypsalo 2× „Haf!“.

No a pokud v té rodičovské metodě chcete mít možnost zavolat i ten svůj původní kód, dáte ho do nějaké privátní metody a tu pak převoláte z té metody, která je překrytelná. Pak si při volání vyberete, kterou metodu použijete, podle toho, zda chcete použít ten váš kód, nebo kód, který mohl někdo v potomcích přetížit.
class Zvíře {

  public void hlas() {
    this.hlasImpl();
  }

  private void hlasImpl() {
    System.out.println("Co to?");
  }

  public void hlasDvakrat() {
    this.hlas();
    this.hlas();
//nebo
    this.hlasImpl();
    this.hlasImpl();
  }
}
4.5. 20:22 Pepek
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
4.5. 21:02 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Že by „rodičovský podobjekt“ znamenalo hypotetickou instanci rodičovské třídy, která by jakoby byla součástí instance třídy potomka?
5.5. 20:19 Pepek
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Chapu to tak, ze v Jave je to objekt super?
5.5. 20:28 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Ano, kdyby v Javě super byl objekt, bylo by to tak.
8.5. 21:29 Andrej | skóre: 43 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Studijní materiál je trochu blábolivý. Nejlépe se to ilustruje na příkladu. Klíčové je, co je překrytelné a co ne. V tomto ohledu je Java trochu prase, protože změna klíčového slova přístupu (private versus všechno ostatní) mění chování kódu. Tady je příklad:
public class Blah {
    private static class Parent {
        public void write() { writeOne(); writeTwo(); }
        private void writeOne() { System.out.println("private parent"); }
        protected void writeTwo() { System.out.println("protected parent"); }
    }
    private static class Child extends Parent {
        private void writeOne() { System.out.println("private child"); }
        protected void writeTwo() { System.out.println("protected child"); }
    }
    public static void main(String[] unused) {
        new Parent().write();
        new Child().write();
    }
}
$ javac Blah.java
$ java Blah
private parent
protected parent
private parent
protected child
ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
8.5. 21:54 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Proto byla do Javy 5 přidána anotace @Override, díky které může překladač kontrolovat, že nepřekrýváte metodu omylem, nebo že naopak nevytváříte novou metodu tam, kde jste chtěl metodu jenom překrýt.

V tomto ohledu je Java trochu prase, protože změna klíčového slova přístupu (private versus všechno ostatní) mění chování kódu.
Kdyby jenom private metody. U package private metod záleží na tom, v jakém package třída je.
9.5. 02:29 Sten
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
S překrýváním omylem vám @Override nepomůže.
9.5. 07:23 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Pomůže. IDE, kompilátor nebo validátor kódu může ohlásit varování u metody, která překrývá jinou metodu, ale není označena @Override.
9.5. 08:59 dustin | skóre: 60 | blog: dustin
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Přesně tak, velice užitečné.
8.5. 22:08 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Prase je spíš programátor, který tímto způsobem píše své aplikace.

Z programátorského hlediska Child není potomkem Parent, protože normální živé dítě je potomkem dvou rodičů a nedědí po nich všechny vlastnosti.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
9.5. 08:27 krocan
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
To chovani je zcela prizorebe, jak by to podle vas melo fungovat, aby to nebylo "prase"?
9.5. 11:32 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Dá se klíčovým slovem označovat, co je překrývající metoda a co není (to, co dnes volitelně dělá anotace @Override). V některých jazycích se explicitně určuje, co je překrytelná (virtuální) metoda, což u Javy nemá moc význam, protože překrytelné jsou všechny metody, které potomek „vidí“.
9.5. 13:00 krocan
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
To uplne nechapu, co tim chcete rict. Predek ma bud metody privatni, na ty mu nikdo nemuze, nebo ma metody neprivatni final, ty lze volat, ale nelze je prekryt. Zbytek muze potomek prekryt, coz predek umoznuje tim, ze je sam ne-final a prislusne metody udelal ne-final, tedy s tim predem pocita. Co zde schazi za vyjadrovaci prostredky k popisu, co za metody lze a nelze prekryvat?
9.5. 14:10 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
„Schází“ vyjadřovací prostředek, který by říkal, zda metoda může nebo nemůže být překryta. Nyní se tahle vlastnost odvozuje od viditelnosti metody. Nejde o to, že by dnes nebylo jednoznačně dané, zda daná třída určitou metodu může překrýt nebo nemůže – jde o to, že tahle vlastnost je „schovaná“ za něčím jiným.

Já si myslím, že je to tak v Javě správně, ale není to „akademicky čisté“ řešení.
9.5. 16:20 krocan
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
A final slouzi podle vas k cemu?
9.5. 17:06 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
final slouží k tomu, aby bylo možné zakázat překrytí metody, která by jinak podle pravidel mohla být překryta. Existuje v Javě opačné klíčové slovo, které by umožnilo překrýt metodu, která by jinak nemohla být překryta?
9.5. 21:37 krocan
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Ne neexistuje, protoze mit final a zaroven moznost ho zmenit by byl zjevny nesmysl. Proc by pak nekdo final pouzival, kdyz by nic neznamenalo?
9.5. 22:07 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Asi jste zapomněl, o čem diskutujeme. Ne každá metoda v Javě musí mít final, takže je evidentní, že jsem v předchozím komentáři psal o těch metodách, které final nemají.
9.5. 22:12 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Ještě pro upřesnění – existují celkem čtyři stavy. V rodičovské třídě (ignoruju teď abstraktní třídy a rozhraní, v terminologii Javy) může být metoda ve dvou stavech – buď může být překryta, nebo nemůže být překryta. V potomkovi opět může být třída ve dvou stavech – buď překrývá metodu v rodičovské třídě, nebo nepřekrývá. A potomek může být opět rodičovskou třídou další třídy, takž emůžete mít metodu, která překrývá metodu předka, ale nemůže být překryta potomkem. Vy jste psal o jednom klíčovém slovu final, a tím těžko odlišíte čtyři různé stavy.
pavlix avatar 9.5. 22:14 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Evidentní to není. Možná se cítíte lépe, když se vyjadřujete nesrozumitelně a na tom, že vás ostatní nechápou si pak dokazujete vlastní inteligenci. Jsem zvědavý, jestli se na váš styl diskuze někdo chytí a povede s vámi další nesmyslnou výměnu komentářů až po vyčerpání šířky obrazovky na odsazení.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
pavlix avatar 9.5. 18:15 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Už jsme to nedávno diskutovali. Java neposkytuje prostředky pro zpětnou kompatibilitu knihoven. Na to by bylo potřeba, aby bylo u každé metody jednoznačně dané, zda překrývám metodu nebo zakládám zcela novou novou metodu s čirou náhodou shodným jménem. Final je sice hezké vyjádření toho, že některá metoda není určena k překrytí, ale v zásadě neřeší vůbec nic.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
pavlix avatar 9.5. 18:16 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Jen abych to upřesnil, neposkytuje ty prostředky explicitně. Lze to obcházet verzováním tříd nebo interfaces.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
9.5. 22:18 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Jak už jsem psal, tohle řeší anotace @Override, tedy pokud ji důsledně používáte, berete vážně varování kompilátoru, považujete za řešení upozornění na konflikt jmen a nutnost změny názvu, a pokud při změně knihovny vždy znovu zkompilujete aplikaci. Ale pořád je to lepší, než drátem do oka… A běžné chyby, kdy člověk při psaní kódu omylem překryje něco, co nechtěl, nebo naopak vytvoří novou metodu místo překrytí té z potomka, to odhalí spolehlivě.
pavlix avatar 9.5. 22:41 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Neřeší. Ale o tom už se vedla diskuze pod mým blogem.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
10.5. 06:33 Filip Jirsák
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Škoda jen, že ten protipříklad je tajný.
15.5. 21:45 Andrej | skóre: 43 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
To chovani je zcela prizorebe, jak by to podle vas melo fungovat, aby to nebylo "prase"?

Ne, to není přirozené. Ve světě pokřiveném Javou možná ano, ale jinak ne. Všude jinde platí přirozená zásada, že klíčové slovo určující přístupová práva a zapouzdření nemůže samo o sobě změnit chování kódu. Změna takového klíčového slova může samozřejmě způsobit, že se kód nepřeloží (když někdo k metodě ztratí přístup), ale neměla by nikdy nenápadně a bez varování změnit chování kódu. V tomto ohledu je tedy Java prase.

Jak by to mělo fungovat? Jako v C++, ideálně. Odstavec zvaný „Guideline #2: Prefer to make virtual functions private.“ velice pěkně ilustruje, o co se jedná a k čemu to může být užitečné. Že jediná možnost, jak vyrobit v Javě (de facto) nevirtuální metodu, je private metoda, to je zkrátka smutné (chro chro).

Nevirtuální metody v C++ mají při dědičnosti spoustu hezkých aplikací v případech, kdy se chování přetížené metody podstatně liší od původní implementace a kdy je cílem, aby se metoda na všech objektech z dané hierarchie tříd chovala podle toho, co si volající myslí, že daný objekt je, nikoliv podle toho, o kolik generací dědičnosti složitější je ve skutečnosti volaný objekt. Tohle představuje celkem rozsáhlou třídu design patterns, které v Javě buď vůbec neexistují, nebo jsou dosažitelné jedině lámáním přes koleno.

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
15.5. 23:15 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Není to jedno? Stačí použít operátor instanceof a můžeš se zeptat klidně i na prarodiče. Zjišťovat název třídy a pak teprve testovat její název je blbost.

Nebavíme se o přetěžování metod, ale o překrývání (overriding).
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
17.5. 00:43 Andrej | skóre: 43 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník

Jakákoliv obdoba operátoru instanceof vyžaduje alespoň RTTI nebo případně rovnou runtime jako má Java. Není to tedy univerzálně použitelné řešení. instanceof je taková poloreflexe, která všeho všudy ukazuje na chyby v návrhu a na zatloukání čtvercových kolíků do kruhových děr. A právě proto to není jedno. Když chci nevirtuální metodu, nechci ji smolit pomocí několika krypticky pojmenovaných protected, které budou povinně virtuální, jenže co naplat, když chci, aby je potomci viděli, a nebudu při každém volání něco větvit na základě instanceof. Tyhle zlozvyky z Javy mě pokaždé spolehlivě zvednou ze židle až ke stropu.

Ano, bavíme se skutečně o překrývání. Přetěžování se týká parametrů předávaných „zprava“, zatímco překrývání se týká parametru předávaného „zleva“ (this).

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
17.5. 08:59 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Aby bylo jasno: instanceof neobhajuji. Je to jen berlička pro ty, kteří neumí pracovat s polymorfismem.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
pavlix avatar 17.5. 09:05 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
A ty, kteří používají knihovny, které sami nenapsali.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
pavlix avatar 17.5. 09:15 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Jakákoliv obdoba operátoru instanceof vyžaduje alespoň RTTI nebo případně rovnou runtime jako má Java.
Ve skutečnosti to vyžaduje triviální odkaz na informace o třídě, což ale vyžaduje i virtualizace metod.
která všeho všudy ukazuje na chyby v návrhu
To jsou ovšem bez konkrétních příkladů a velmi dobrého zdůvodnění jen prázdná slova.
a na zatloukání čtvercových kolíků do kruhových děr.
Na zatloukání čtvercových kolíků do kruhových děr nevidím nic špatného, ty díry jsou tam od toho, aby byl na kolíky trochu prostor, ne aby byly dokonale stejné. Teda aspoň pokud se bavíme o zatloukání kolíků do hlíny.

Hromada řečí, argumenty žádné.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
16.5. 09:42 krocan
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Nevim co mate na mysli tim, ze jedina moznost jak "vyrobit nevirtualni metodu" je private metoda - k tomu klicove slovo final. Ze je nevirtualni i private metoda je pouze vedlejsi efekt toho, ze metoda neni mimo svou tridu zadnym zpusobem videt. Mechanismus pouzivany v jave nemusi byt idealni, ale vetsina kritiky napr. od programatoru C++ (ktere ma jine vyjadrovaci prostredky) vychazi z toho, ze nemaji s javou zkusenost.

Volat metodu podle toho, "co si volající myslí, že daný objekt je, nikoliv podle toho, o kolik generací dědičnosti složitější je ve skutečnosti volaný objekt" je pozadavek zcela mimo bezne pojeti polymorfismu a pokud nastava, tak jde ve vetsine pripadu o nevhodne pouziti dedicnosti na neco, co realne dedicnost neni.
16.5. 10:23 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Pokud potomka definujete uvnitř rodičovské třídy, vidí potomek i private metody rodiče. Překrýt je ale nemůže. V Javě se prostě to, zda metoda je nebo není virtuální, odvozuje pomocí určitých pravidel z ostatních vlastností té metody. Což na jednu stranu zjednodušuje jazyk (programátor nemusí vědět nic o virtuálních metodách a v obvyklých případech to funguje tak, jak by intuitivně očekával), na druhou stranu to opravdu není úplně čisté řešení. A ještě horší je to na straně potomků, protože tam se to, zda metoda jinou metodu překrývá nebo ne, může změnit, aniž byste ve svém kódu udělal jedinou změnu.
16.5. 10:47 dustin | skóre: 60 | blog: dustin
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
A "čistým" řešením je definovat potomka v rodičovské třídě?
16.5. 10:52 krocan
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Inner class z principu nabourava zapouzdreni a private metodu vidi proto, ze je inner vlastnici tridy, nikoliv proto, ze je jejim potomkem. Nemuze ji prekryt ve smyslu dedicnosti, protoze private metodu prekryt nelze, ale technicky - tedy vytvorenim stejne metody - ji prekryt muze.

Na strane potomka by nemela byt zadna tragedie, pokud nevi, zda prekryva metodu predka. V zasade jsou z pohledu potomka dva scenare. Bud metodu predka ve sve metode vyuziva a vola ji pres super, nebo ji vubec nevyuziva a svoji samostatnou implementaci. Pokud metodu pouziva, tak po odstraneni nebo zmene signatury v predkovi se uz neprelozi. Pokud nepouziva, tak by melo byt jedno, zda se jedna o prekryti metody nebo ne. Presneji jedno to samozrejme neni, ale je to na stejne urovni, jako jine zavazne zmeny kontraktu predka - pokud kontrakt nekdo zmeni, tak neni zadna zaruka, ze potomek bude i nadale spravne fungovat.
pavlix avatar 16.5. 11:25 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Čuchám čuchám problémy s terminologií.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.
16.5. 11:40 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Ten příklad s inner class jsem uváděl jenom proto, že neplatí pravidlo, že metodu, kterou vidím a není final, můžu překrýt.
Bud metodu predka ve sve metode vyuziva a vola ji pres super, nebo ji vubec nevyuziva a svoji samostatnou implementaci.
O tohle nejde, problém je v opačném směru – pokud kód předka volá překrytou metodu. Normálně by přidání nové metody do rozhraní nemělo být závažnou změnou kontraktu a mělo by být zpětně kompatibilní. Jenže se může stát, že se ta nová metoda zrovna „trefí“ do metody, která už je v potomkovi definovaná, a tím pádem ta metoda v potomkovi najednou nechtěně překryje metodu předka – a bude volána v kontextu, v jakém to nebylo zamýšleno.
16.5. 12:18 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Jenže ta veřejná metoda rodiče je součástí rozhraní, takže o tom ten potomek musí vědět. Privátní metoda nebude překryta. Nechtěnost je tedy vyloučena.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
16.5. 14:14 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Knihovna verze 1:
public class Rodic {
  public void run() {
    step1();
    step2();
    step3();
  }

  protected void step1() {
  }

  protected void step2() {
  }

  protected void step3() {
  }
}
Aplikace
public class Dite {
  protected void validate() {
  }
}
Knihovna verze 2:
public class Rodic {
  public void run() {
    validate();
    step1();
    step2();
    step3();
  }

  protected void step1() {
  }

  protected void step2() {
  }

  protected void step3() {
  }

  protected void validate() {
  }
}
16.5. 15:56 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Hmm, blbě se to vysvětluje, když dítě není rodičem...
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
16.5. 16:08 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Pardon, třída Dite má být Dite extends Rodic. Ale jinak je snad jasné, o co jde – aplikace si ve třídě Dite nadefinuje nějakou metodu (zde validate()) pro tuto třídu a její potomky, ta metoda nemá nic společného s rodičovskou třídou. Když ale v rodičovské třídě v další verzi knihovny přibyde virtuální metoda validate() se správnou signaturou, ta metoda Dite.validate() najednou bude překrývající metodou. Přitom ta metoda může dělat něco úplně jiného, překrytí nebyl záměr, a dokud se ten kód třídy Dite znovu nezkompiluje, tak se o tom ani nedozvím. Přitom změna v té knihovně byla zdánlivě zpětně kompatibilní a neměla by rozbít žádný stávající kód.
16.5. 17:45 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Myslel jsem to v reálu. Dítě nemůže být rodičem, protože nemá všechny jeho atributy ani chování. Když je malé, tak ani nemůže mít další děti. V daném kontextu prostě sémantika silně kulhá.

Proto jsem ve svém příkladu uvedl Duck extends Bird. Kachna je ptákem. Má křídla jako pták, létá jako pták, ale vydává jiné zvuky než ostatní ptáci. Proto je metoda pro pípání překryta metodou pro kvákání.

A teď: Je nějaký důvod, proč by měla kachna pípat? Není. Proto ani není důvod, proč by se měla volat metoda rodiče, pokud je překryta.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
16.5. 18:26 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Ty třídy jsem tak pojmenoval pouze pro názornost. Můžete si je pojmenovat jak chcete, na podstatě věci to nic nezmění. V tom příkladu jde o to, že ta metoda rodiče je překryta omylem.
metoda rodiče, pokud je překryta
A v tom je právě ten problém. Já napíšu kód, který metodu rodiče nepřekrývá, a aniž bych ho změnil, najednou nějakou metodu rodiče překrývá.
16.5. 19:44 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Netuším, proč je v tom příkladu všude protected místo praktičtějšího private. S tím by se to přece nemohlo stát.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
16.5. 22:44 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Aby bylo možné to v potomcích zavolat nebo překrýt. To mám nejradši ty knihovní třídy, které všechno zajímavé implementují v privátních metodách, takže když pak chcete změnit chování jediného řádku v té třídě, musíte ji stejně celou zkopírovat.
16.5. 23:35 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Podobně to dopadá i s třídami, ve kterých jsou metody nebo rovnou celá třída final...
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
9.5. 14:29 Kit | skóre: 37 | Brno
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
Zkus se zamyslet, zda ten pták bude pípat nebo kvákat. Můžeš si to i přeložit a spustit:
public class Bird {

    public static void main(String[] args) {
        Bird bird = new Duck();
        System.out.println(bird.sing());
    }

    public String sing() {
        return "Beep";
    }
}

class Duck extends Bird {

    @Override
    public String sing() {
        return "Quack";
    }
}
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Řešení 1× (Bystroushaak)
pavlix avatar 9.5. 16:48 pavlix | skóre: 53 | blog: pavlix
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
"Rodičovský podobjekt nemůže poslat překrytelnou zprávu sám sobě. Jakoukoliv překrytelnou zprávu totiž musí poslat znovu „nejvnějšnější“ instanci, v jejíchž útrobách se nachází (dceři, vnučce, pravnučce–prostě té, která už není ničím rodičovským podobjektem)."
Materiály rituálně spálit a v případě elektronické podoby rozmlátit médium kladivem. Nejsem nějaký javista, ale pokud vím, tak si zprávy posílají (prostřednictvím volání metod) objekty. Pojem podobjekt dává smysl snad jen v datovém smyslu a chápal bych to u nějakého hrubšího jazyka jako je C nebo C++, ale možná se pletu. Vnější a vnitřní instance a tedy i nejvnějšnější instance mi připadají jako prázdné pojmy.

Mám instanci (obecněji objekt), na tu se můžu dívat jako na instanci třídy, kterou skutečně je, nebo jako na instanci některé z nadřazených tříd v hierarchii dědičnosti. Volat metody může kdokoli, kdo ví o dané instanci. Volat může takové metody, které jsou definovány pro třídu pod kterou instance momentálně vystupuje.

Ten popis mi připadá jako kdyby používal úplně jinou abstrakci než je v OOP běžná, a které je bližší spíše nějakému fyzickému paměťovému modelu. Ano instance podtřídy opravdu typicky musí nějak uložit podobjekt odpovídající nadtřídě. Ale psát, že tomu podobjektu něco posílá je úplně zbytečná personifikace. Pokud chce člověk mluvit v jazyce hardware, provádějí se instrukce a ukládá se na paměťová místa, pokud chce člověk mluvit v jazyce návrhu, „komunikují“ mezi sebou celé objekty pomocí metod, ale tenhle kočkopes je dobrý možná tak pro vývojáře VM.
GentooFedoraSCRAM – Jsem open source vývojář, nikoli markeťák ⇒ názory zde uvedené jsou jen mé vlastní.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.