The impoliteness of overriding methods

Timon Gehr timon.gehr at gmx.ch
Fri Dec 21 00:59:32 PST 2012


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();
	}






More information about the Digitalmars-d mailing list