The Non-Virtual Interface idiom in D

Yigal Chripun yigal100 at gmail.com
Sat Sep 26 10:24:02 PDT 2009


On 25/09/2009 23:49, Andrei Alexandrescu wrote:
> In this article:
>
> http://www.gotw.ca/publications/mill18.htm
>
> Herb Sutter makes a powerful argument that overridable functions
> (customization points) should actually not be the same as the publically
> available interface. This view rhymes with the Template Method pattern
> as well.
>
> This leads to the interesting setup in which an interface should ideally
> define some signatures of to-be-defined functions, but disallow client
> code from calling them. For the clients, the same interface should
> expose some higher-level final functions.
>
> Ignoring for the moment access protection semantics in D (which are
> broken anyway), let's say this would work:
>
> interface Cloneable(T) if (is(T == class))
> {
> private T doClone(); // must implement but can't call
> T clone() // this is what everybody can call
> {
> auto result = doClone();
> assert(typeof(result) == typeof(this));
> assert(this.equals(result));
> return result;
> }
> }
>
> So clients must implement doClone, but nobody can ever call it except
> Cloneable's module. This ensures that no cloning ever gets away with
> returning the wrong object.
>
> Pretty powerful, eh? Now, sometimes you do want to allow a derived class
> to call the base class implementation. In that case, the interface
> function must be protected:
>
> interface ComparableForEquality(T)
> {
> protected bool doEquals(T);
> final bool equals(T rhs)
> {
> auto result = doEquals(rhs);
> assert(rhs.equals(cast(T) this) == result);
> return result;
> }
> }
>
> The difference is that now a derived class could call super.doEquals.
>
> This feature would require changing some protection rules, I think for
> the better. What do you think?
>
>
> Andrei

to clarify your suggestion above I have a few questions:
are the functions with definitions always final?

interface A {
    final func () {...}
}
interface B {
    final func () {...}
}

class C : A, B {...}
auto obj = new C;
C.func(); // what happens here?



More information about the Digitalmars-d mailing list