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