December 20, 2012
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

-- 
Just because you survived after you did it, doesn't mean it wasn't stupid!
December 20, 2012
On 12/20/12, foobar <foo@bar.com> wrote:
> It's all a matter of trade-offs and we cannot and should not strive to put all possible feature combinations and implementation variants into D.

Woops, I'm sorry if it appeared that way but I didn't suggest adding this feature to D. It was interesting enough to be put here for discussion (hey if bearophile can post about other langs.. :p). I wonder though if the new UDA stuff can generally help out in API design.
December 21, 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();
	}




1 2 3 4
Next ›   Last »