Diskuze: Zděděné soukromé metody

Java Java Zděděné soukromé metody

Avatar
bortomar
Člen
Avatar
bortomar:

Ahoj, rád bych se zeptal, nemáte-li nějakou mnemotechnickou pomůcku pro to, abyste si uvědomili, že v případě, kdy voláte v těle zděděné metody jinou zděděnou metodu, ovšem soukromou, bude zavolána soukromá metoda rodiče, třebaže implementaci zděděné soukromé metody máte i v potomkovi? Uvedu příklad.

public class A {
    private void foo() {
        System.out.println("A");
    }

    public void bar() {
        foo();
    }
}

public class B extends A {
    private void foo() {
        System.out.println("B");
}

B b = new B();
b.bar();                // vytiskne: A

Metoda bar() je přeci volána v kontextu instance třídy B, proto by měla vidět na své soukromé členy, nikoliv na soukromé členy rodiče. Změním-li modifikátor private na protected, vše funguje podle představ. Připadá mi to dost neintuitivní. Například v Ruby by se vytisklo B, což znamená, že soukromá metoda byla překryta, což mi připadá daleko logičtější.

Můžete mi zkusit poradit, jak změnit pohled na dědičnost v Javě tak, aby mi to připadalo přirozenější?

Díky

Editováno 8.9.2015 15:11
 
Odpovědět 8.9.2015 15:09
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na bortomar
Jan Vargovský:

To co hledáš je virtuální/abstrak­tní metody. Popřípadě ještě termín tabulka virtuálních metod.

 
Nahoru Odpovědět  +1 8.9.2015 16:19
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na bortomar
Jindřich Máca:

Ahoj, řeknu to jednoduše. Tady je zkrátka mezi Ruby a Javou rozdíl. :-D

Je to napsané i v dokumentaci. Ruby volá private metody vždy v kontextu self, zato v Jave se volá metoda předka tudíž se volá private v kontextu předka. :-) Pokud chceš v Jave dosáhnout stejného chování, správně jsi pochopil, že musíš použít protected. Mě osobně asi dává smysl obojí a každé má své pro a proti. :-) Pokud se chceš dozvědět o této problematice víc, není nic spolehlivějšího než oficiální dokumentace https://docs.oracle.com/…control.html

A jedna poznámka na závěr, private metody se nikdy nedědí! :-P

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět  +2 8.9.2015 16:26
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na bortomar
Jindřich Máca:

Ahoj, řeknu to jednoduše. Tady je zkrátka mezi Ruby a Javou rozdíl. :-D

Je to napsané i v dokumentaci. Ruby volá private metody vždy v kontextu self, zato v Jave se volá metoda předka tudíž se volá private v kontextu předka. :-) Pokud chceš v Jave dosáhnout stejného chování, správně jsi pochopil, že musíš použít protected. Mě osobně asi dává smysl obojí a každé má své pro a proti. :-) Pokud se chceš dozvědět o této problematice víc, není nic spolehlivějšího než oficiální dokumentace https://docs.oracle.com/…control.html

A jedna poznámka na závěr, private metody se nikdy nedědí! :-P

 
Nahoru Odpovědět 8.9.2015 16:26
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Jindřich Máca
Jindřich Máca:

Omlouvám se, nějakou chybou se ten komentář odeslal 2x. :-D

Bug report to David Čápka

 
Nahoru Odpovědět 8.9.2015 16:28
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Jindřich Máca
Jan Vargovský:

Ale sedí, jen k nim nemáš přístup...

 
Nahoru Odpovědět  +1 8.9.2015 16:31
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Jan Vargovský
Jan Vargovský:

Dědí*. Nevidím edit button.

 
Nahoru Odpovědět  +1 8.9.2015 16:34
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Jan Vargovský
Jindřich Máca:

Tak jako dědí, ale když k nim nemáš přístup a dokonce můžeš bez problémů napsat do potomka úplně stejnou metodu bez konfliktu, tak to je jako kdyby tam vůbec nebyli, nemyslíš? :-)

 
Nahoru Odpovědět 8.9.2015 16:38
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Jindřich Máca
Jan Vargovský:

To ti to nedá žádný warning? V C# dostaneš warning a měl bys k signature přidat new. Jako tam nejsou, mas pravdu, ale ve skutečnosti tam jsou :D

 
Nahoru Odpovědět  +1 8.9.2015 16:42
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Jan Vargovský
Jindřich Máca:

No, warning Ti dá možná tak některé IDE, ale to neznamená, že to nezkompiluješ a nespustíš. :-P (alespoň tedy v Jave)

Editováno 8.9.2015 16:59
 
Nahoru Odpovědět 8.9.2015 16:58
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Jindřich Máca
Jan Vargovský:

Jo, sorry. Máš pravdu... Ono to hlásí, jen když jsou ty metody public. Každopádně warningy nejsou z IDE, ale z kompilátoru :)

 
Nahoru Odpovědět  +1 8.9.2015 17:44
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Jan Vargovský
Jindřich Máca:

Jo, já jsem to myslel tak, že warningy tam nejsou, jen Tě na to nějak upozorní IDE. :D

 
Nahoru Odpovědět 8.9.2015 17:53
Avatar
coells
Redaktor
Avatar
Odpovídá na Jan Vargovský
coells:

Private members třídy se opravdu nedědí, dědičnost se vztahuje jen na protected a public members.

 
Nahoru Odpovědět  +1 8.9.2015 18:00
Avatar
bortomar
Člen
Avatar
bortomar:

Ještě jednou díky. Zdá se, že Ruby je ve skutečnosti jednou z výjimek a většina jazyků naopak přistupuje k problému stejně jako Java.

 
Nahoru Odpovědět  +1 9.9.2015 9:47
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 14 zpráv z 14.