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