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í
×
včera 23:45 | Zajímavý software

Na blogu Qt bylo představeno Qt 3D Studio. Jedná se o produkt dosud známý pod názvem NVIDIA DRIVE™ Design Studio. NVIDIA jej věnovala Qt. Jedná se o několik set tisíc řádků zdrojového kódu. Qt 3D Studio bude stejně jako Qt k dispozici jak pod open source, tak pod komerční licencí. Ukázka práce s Qt 3D Studiem na YouTube.

Ladislav Hagara | Komentářů: 5
včera 17:50 | Komunita

Nadace The Document Foundation (TDF) zastřešující vývoj svobodného kancelářského balíku LibreOffice slaví 5 let od svého oficiálního vzniku. Nadace byla představena 28. září 2010. Formálně byla založena ale až 17. února 2012.

Ladislav Hagara | Komentářů: 0
včera 12:50 | Komunita

Mozilla.cz informuje, že dosud experimentální funkce Page Shot z programu Firefox Test Pilot (zprávička) se stane součástí Firefoxu. Page Shot je nástroj pro vytváření snímků webových stránek. Umí výběr oblasti, prvku stránky (např. odstavce), nebo uložení snímku celé stránky. Snímky lze ukládat na disk nebo nahrávat na server Mozilly. Nedávno bylo oznámeno, že se součástí Firefoxu stane Activity Stream.

Ladislav Hagara | Komentářů: 25
včera 04:10 | Nová verze

Po 10 týdnech vývoje od vydání Linuxu 4.9 (zprávička) oznámil Linus Torvalds, mj. již 20 let žijící v USA, vydání Linuxu 4.10 (LKML). Přehled nových vlastností a vylepšení například na Kernel Newbies a v Jaderných novinách (1, 2 a 3). Kódové jméno Linuxu 4.10 je Fearless Coyote.

Ladislav Hagara | Komentářů: 10
19.2. 15:55 | Zajímavý projekt

Vyzkoušet si příkazy a vyřešit několik úkolů lze na stránkách Commandline Challenge (CMD Challenge). Úkoly lze řešit různými způsoby, důležitý je výsledek. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.

Ladislav Hagara | Komentářů: 18
18.2. 17:35 | Bezpečnostní upozornění

Německá Bundesnetzagentur (obdoba českého ČTU) zakázala na německém území prodej panenky Cayla kvůli „špionáži“ dětí. Tato elektronická hračka obsahuje mikrofon, reproduktor a kameru a bezdrátové komunikační rozhraní, pomocí kterého se hračka připojuje na servery výrobce. Takovýmto způsobem může hračka pomocí umělé inteligence „odpovídat“ na dotazy dítěte. Hlavní problém bude ale asi někde jinde, podle prvotních zpráv může

… více »
Petr Tomášek | Komentářů: 34
17.2. 15:30 | Bezpečnostní upozornění

CSIRT.CZ upozorňuje, že bezpečnostní experti objevili nový typ malwaru, jenž cílí na open source e-commerce platformu Magento. Malware je zajímavý tím, že se jedná o první svého druhu, jehož kód zůstává skrytý v SQL databázi zasaženého e-shopu. Škodlivý kód je volán pomocí tzv. SQL trigerru, který je spouštěn při každém vytvoření objednávky v systému.

Ladislav Hagara | Komentářů: 5
17.2. 09:00 | Nová verze

Bylo vydáno Ubuntu 16.04.2 LTS, tj. druhé opravné vydání Ubuntu 16.04 LTS s kódovým názvem Xenial Xerus. Přehled novinek v poznámkách k vydání a v přehledu změn.

Ladislav Hagara | Komentářů: 60
17.2. 06:00 | Zajímavý článek

Pavel Tišnovský se v dvoudílném článku na MojeFedora.cz věnuje tvorbě pluginů (modulů) pro bitmapový grafický editor GIMP. Pomocí pluginů lze GIMP rozšiřovat o další funkce. Implementovat lze například nové filtry nebo pomocné utility pro tvorbu animací či poloautomatickou retuš snímků.

Ladislav Hagara | Komentářů: 6
16.2. 23:32 | Komunita

Do 30. března se lze přihlásit do dalšího kola programu Outreachy, jehož cílem je přitáhnout do světa svobodného a otevřeného softwaru lidi ze skupin, jež jsou ve světě svobodného a otevřeného softwaru málo zastoupeny. Za 3 měsíce práce, od 30. května do 30. srpna 2017, v participujících organizacích lze vydělat 5 500 USD. Jedná se již o 14. kolo tohoto programu.

Ladislav Hagara | Komentářů: 11
Jak se stavíte k trendu ztenčování přenosných zařízení (smartphony, notebooky)?
 (13%)
 (2%)
 (72%)
 (3%)
 (10%)
Celkem 675 hlasů
 Komentářů: 61, poslední dnes 13:06
Rozcestník
Reklama

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

4.5.2016 17:10 Fatboy
Základy dědění v Javě - začátečník
Přečteno: 995×
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.2016 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.2016 20:22 Pepek
Rozbalit Rozbalit vše Re: Základy dědění v Javě - začátečník
4.5.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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í.
pavlix avatar 9.5.2016 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.
pavlix avatar 9.5.2016 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.
9.5.2016 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.2016 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.
10.5.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.
pavlix avatar 17.5.2016 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é.
16.5.2016 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.2016 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.2016 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.2016 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.2016 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í.
16.5.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.2016 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.

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.