abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 04:44 | Nová verze

    Nová čísla časopisů od nakladatelství Raspberry Pi: MagPi 140 (pdf) a HackSpace 77 (pdf).

    Ladislav Hagara | Komentářů: 0
    dnes 01:00 | Nová verze

    ESPHome, tj. open source systém umožňující nastavovat zařízení s čipy ESP (i dalšími) pomocí konfiguračních souborů a připojit je do domácí automatizace, například do Home Assistantu, byl vydán ve verzi 2024.4.0.

    Ladislav Hagara | Komentářů: 0
    včera 22:11 | IT novinky Ladislav Hagara | Komentářů: 0
    včera 20:55 | Nová verze

    Neziskové průmyslové konsorcium Khronos Group vydalo verzi 1.1 specifikace OpenXR (Wikipedie), tj. standardu specifikujícího přístup k platformám a zařízením pro XR, tj. platformám a zařízením pro AR (rozšířenou realitu) a VR (virtuální realitu). Do základu se z rozšíření dostalo XR_EXT_local_floor. Společnost Collabora implementuje novou verzi specifikace do platformy Monado, tj. open source implementace OpenXR.

    Ladislav Hagara | Komentářů: 2
    včera 17:22 | Nová verze

    Byla vydána nová verze 0.38.0 multimediálního přehrávače mpv (Wikipedie) vycházejícího z přehrávačů MPlayer a mplayer2. Přehled novinek, změn a oprav na GitHubu. Požadován je FFmpeg 4.4 nebo novější a také libplacebo 6.338.2 nebo novější.

    Ladislav Hagara | Komentářů: 1
    včera 17:11 | Nová verze

    ClamAV (Wikipedie), tj. multiplatformní antivirový engine s otevřeným zdrojovým kódem pro detekci trojských koní, virů, malwaru a dalších škodlivých hrozeb, byl vydán ve verzích 1.3.1, 1.2.3 a 1.0.6. Ve verzi 1.3.1 je mimo jiné řešena bezpečnostní chyba CVE-2024-20380.

    Ladislav Hagara | Komentářů: 1
    včera 12:11 | IT novinky

    Digitální a informační agentura (DIA) oznámila (PDF, X a Facebook), že mobilní aplikace Portál občana je ode dneška oficiálně venku.

    Ladislav Hagara | Komentářů: 8
    včera 05:11 | Komunita

    #HACKUJBRNO 2024, byly zveřejněny výsledky a výstupy hackathonu města Brna nad otevřenými městskými daty, který se konal 13. a 14. dubna 2024.

    Ladislav Hagara | Komentářů: 2
    17.4. 17:55 | IT novinky

    Společnost Volla Systeme stojící za telefony Volla spustila na Kickstarteru kampaň na podporu tabletu Volla Tablet s Volla OS nebo Ubuntu Touch.

    Ladislav Hagara | Komentářů: 3
    17.4. 17:44 | IT novinky

    Společnost Boston Dynamics oznámila, že humanoidní hydraulický robot HD Atlas šel do důchodu (YouTube). Nastupuje nová vylepšená elektrická varianta (YouTube).

    Ladislav Hagara | Komentářů: 1
    KDE Plasma 6
     (68%)
     (10%)
     (2%)
     (20%)
    Celkem 557 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    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: 1168×
    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: 51 | blog: Republic of Mordor
    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: 63 | 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: 45 | 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: 54 | 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í.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    pavlix avatar 9.5.2016 18:15 pavlix | skóre: 54 | 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.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    pavlix avatar 9.5.2016 18:16 pavlix | skóre: 54 | 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.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    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: 54 | 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.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    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: 51 | blog: Republic of Mordor
    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: 45 | 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: 51 | blog: Republic of Mordor
    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: 45 | 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: 54 | 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.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    pavlix avatar 17.5.2016 09:15 pavlix | skóre: 54 | 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é.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    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: 68 | 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: 63 | 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: 54 | 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í.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.
    16.5.2016 11:40 Filip Jirsák | skóre: 68 | 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: 45 | 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: 68 | 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: 45 | 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: 68 | 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: 45 | 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: 68 | 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: 45 | 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: 68 | 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: 45 | 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: 45 | 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.
    pavlix avatar 9.5.2016 16:48 pavlix | skóre: 54 | 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.
    Já už tu vlastně ani nejsem. Abclinuxu umřelo.

    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.