On 12/20/2012 11:41 PM, H. S. Teoh wrote:
On Thu, Dec 20, 2012 at 11:33:56PM +0100, Timon Gehr wrote:
On 12/20/2012 08:44 PM, H. S. Teoh wrote:
...
They also make your derived classes immovable around the hierarchy,
because to override their parent's method, they have to use the exact
name that's introduced by the parent class, otherwise they risk
accidentally short-circuiting part of the chain.
...


That's what 'final' is for.

That doesn't work in all cases:

        class Base {
                void precious() {
                        // invokes subclass method
                        preciousHook1();
                }
                abstract void preciousHook1();
        }

        class Derived1 : Base {
                override void preciousHook1() {
                        // invokes subclass method
                        preciousHook2();
                }
                abstract void preciousHook2();
        }

        class Derived2 : Derived1 {
                override void preciousHook2() {
                        // invokes subclass method
                        preciousHook3();
                }
                abstract void preciousHook3();
        }

        class Broken : Derived2 {
                override void preciousHook2() {  // <-- oops, override wrong 
method
                        preciousHook4();
                }
                abstract void preciousHook4();
        }

The chain is intended to go precious -> preciousHook1 -> preciousHook2
-> preciousHook3 -> preciousHook4, but due to the typo in Broken,
preciousHook3 is skipped over. And depending on the naming convention,
this can be rather hard to catch (what if Broken was originally derived
from Derived1, and was subsequently moved to derive from Derived2? The
code will still compile with no indication that a problem was
introduced).


T



        class Base {
                void precious() {
                        // invokes subclass method
                        preciousHook1();
                }
                abstract void preciousHook1();
        }

        class Derived1 : Base {
                final override void preciousHook1() {
                        // invokes subclass method
                        preciousHook2();
                }
                abstract void preciousHook2();
        }

        class Derived2 : Derived1 {
                final override void preciousHook2() {
                        // invokes subclass method
                        preciousHook3();
                }
                abstract void preciousHook3();
        }

        class Broken : Derived2 {
                final override void preciousHook2() {    // <-- caught by 
compiler
                        preciousHook4();
                }
                abstract void preciousHook4();
        }




Reply via email to