Interfaces allow member definitions?

TheFlyingFiddle theflyingfiddle at gmail.com
Thu Jan 30 03:29:54 PST 2014


On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote:
> I was, I think, able to call an interface's method. I had the
> code like the following
>
>
> interface A
> {
>      void foo();
> }
>
> class B : A { void foo() { writeln("Hey"); } }
> class C : A { void foo() { writeln("You"); } }
>
> yet, when I called a.foo(); I did not get any output. (A being 
> of
> type A)
>
>
> Now, I was doing some weird stuff but either in the vtable for 
> A,
> there are empty functions that do nothing or I just happen to
> call bogus memory that did not throw an exception.
>
> The real question is, do interface methods actually support
> function definitions?
>
> Is there anything that stops us from actually doing
>
> interface A
> {
>      void foo() { writeln("What up!!"); }
> }
>
> internally? I know member functions require a this but in this
> case foo does not require this so it any this would work.
>
> Basically, does the vtable contain storage for the interface's
> members but blocks us from using them due to the issue with 
> this?
>
> If so, then shouldn't we be able to create functions in an
> interface as long as they do not reference this? (basically
> static functions that can be overriden as dynamic functions in
> the class)
>
> e.g.,
>
> interface A
> {
>          // default behavior for foo and bar
>          void foo() { writeln("asdasdfasdfasdf"); }
> 	void bar() { writeln("1234"); }
>
> }
>
> class B : A
> {
> 	void foo() { writeln("help"); }
> }
>
> void main()
> {
> 	A a = new B;
>          a.foo(); // prints help
>          a.bar(); // prints 1234
>          B b = new B;
>          b.foo(); // prints help
>          b.bar(); // prints 1234
> }
>
>
> This would allow one to sort of add default behavior to an
> interface(limited since no fields could be used but properties
> help with it).
>
> basically the vtable just needs an extra spot for the interface
> methods and calls them with null or the object it contains for
> this... which doesn't matter since this is never used in the 
> body
> of the function.

You can already do this using the Non-virtual interface ideom


interface Foo
{
    final void bar() { writeln("Something"); }
    void baz() { writeln("Something Else"); }
}

Note the final keyword it is imortant here. This will make bar 
simply be a non-virutal method in Foo.

If you want to provide some basic implementation but still 
forward to a base class you can do something like this.

interface Foo2
{
    final void bar(uint i)
    {
        // Does some basic stuff here.
        bar_impl(i);
    }

    protected void bar_impl(uint i);
}


class A : Foo2
{
    protected void bar_impl(uint i)
    {
       //Do some specific stuff here.
    }
}

This pattern allows you to do some basic stuff in bar and more 
specialized stuff in bar_impl. It does require that you overload 
bar_impl though which may not be what you want.


More information about the Digitalmars-d-learn mailing list