The impoliteness of overriding methods

Paulo Pinto pjmlp at progtools.org
Thu Dec 20 01:42:20 PST 2012


On Thursday, 20 December 2012 at 08:35:34 UTC, foobar wrote:
> On Thursday, 20 December 2012 at 08:12:54 UTC, Paulo Pinto 
> wrote:
>> On Thursday, 20 December 2012 at 07:48:12 UTC, foobar wrote:
>>> On Thursday, 20 December 2012 at 00:07:49 UTC, H. S. Teoh 
>>> wrote:
>>>> On Thu, Dec 20, 2012 at 12:11:34AM +0100, Andrej Mitrovic 
>>>> wrote:
>>>>> Some interesting blog post:
>>>>> http://journal.stuffwithstuff.com/2012/12/19/the-impoliteness-of-overriding-methods/
>>>>> 
>>>>> It's a post about a common problem in class design, I've 
>>>>> ran into it a
>>>>> few times in D too.
>>>> [...]
>>>>
>>>> Interesting concept. So "polite" overriding is simply a kind 
>>>> of override
>>>> where the derived class method has a vtable entry separate 
>>>> from the base
>>>> class method's entry (and thus needs explicit invocation 
>>>> from the base
>>>> class), whereas the usual "impolite" overriding is a kind of 
>>>> override
>>>> where the derived class method replaces the vtable entry of 
>>>> the base
>>>> class method.
>>>>
>>>> I can see use cases for both kinds of overriding.
>>>>
>>>> Interestingly enough, in the "polite" overriding case, the 
>>>> call to inner
>>>> is undefined until it's defined in the derived class. Which 
>>>> means that a
>>>> method that calls inner is a kind of pseudo-abstract method 
>>>> (since
>>>> abstract methods are those that *must* be implemented by the 
>>>> derived
>>>> class). So if we were to implement this in D, we could 
>>>> extend the
>>>> meaning of 'abstract':
>>>>
>>>> 	class Base {
>>>> 		// The current, usual overridable method
>>>> 		void replaceMe() {
>>>> 			writeln("A");
>>>> 		}
>>>>
>>>> 		// Abstract, because chain(chainMe) is undefined until
>>>> 		// the derived class implements it.
>>>> 		abstract void chainMe() {
>>>> 			writeln("B");
>>>> 			inner.chainMe(); // call derived class method
>>>> 					// 'inner' is a tentative
>>>> 					// keyword
>>>> 			writeln("C");
>>>> 		}
>>>> 	}
>>>>
>>>> 	class Derived : Base {
>>>> 		override replaceMe() {
>>>> 			writeln("D");
>>>> 			Base.replaceMe();
>>>> 			writeln("E");
>>>> 		}
>>>>
>>>> 		// Base.chainMe is abstract, so we have to implement
>>>> 		// this method.
>>>> 		override void chainMe() {
>>>> 			writeln("F");
>>>> 		}
>>>> 	}
>>>>
>>>> 	void main() {
>>>> 		auto d = new Derived();
>>>> 		d.replaceMe();	// prints D A E
>>>> 		d.chainMe();	// prints B F C
>>>> 	}
>>>>
>>>>
>>>> T
>>>
>>> This is trivially implemented with a simple OO design pattern 
>>> in any usual OO language:
>>>
>>> class Base {
>>> public override precious() {...}
>>> private void myPrecious() {
>>>   before();
>>>   precious();
>>>   after();
>>> }
>>> }
>>>
>>> class Derived {
>>> override precious() {...}
>>> }
>>>
>>> Having syntax sugar is redundant given how simple this 
>>> pattern is.
>>
>> No because in your example you have to write Base already for 
>> that specific use case, whereas in BETA is up to the derived 
>> class to do as it please.
>
> Have you read the article?
> The Beta design (btw, it's the same in smalltalk - the article 
> is wrong on that point) is to give control to the base class. 
> The base class in beta is written specifically for that use 
> case and the derived has no-control. That's the entire point of 
> this design. It is basically a restriction to allow only 
> overriding abstract methods (with a slightly more convenient 
> syntax)

Me bad.

I just skimmed thru it yesterday, so I missed the main issue.

Sorry about that.


More information about the Digitalmars-d mailing list