Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 30, 2014 Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
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. |
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | 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.
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | Compiling with DMD 2.064, I am NOT able to get any function in interfaces accepted unless they are final. This means you cannot provide default behavior in the interface, at least not in the ways shown above. |
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Casper Færgemand | On Thursday, 30 January 2014 at 13:43:49 UTC, Casper Færgemand wrote:
> Compiling with DMD 2.064, I am NOT able to get any function in interfaces accepted unless they are final. This means you cannot provide default behavior in the interface, at least not in the ways shown above.
Yes the void baz() method is incorrect. The rest should be fine though.
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | On Thursday, 30 January 2014 at 11:29:55 UTC, TheFlyingFiddle
wrote:
> 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.
But this is not what I am talking about. Obviously one could use
a multitude of ways to accomplish the same task but nothing is
simple, direct, and elegant.
Do you realize you have to define two functions in the interface?
I'm not asking about a work around but if what I am talking about
can actually be done(does the vtable support this or can made to
support it?)
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On Thursday, 30 January 2014 at 14:31:05 UTC, Frustrated wrote:
> I'm not asking about a work around but if what I am talking about
> can actually be done(does the vtable support this or can made to
> support it?)
It would work if you changed the interface to an abstract class.
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On Thu, 30 Jan 2014 09:31:05 -0500, Frustrated <c1514843@drdrb.com> wrote:
> I'm not asking about a work around but if what I am talking about
> can actually be done(does the vtable support this or can made to
> support it?)
Yes. Interfaces have no concrete vtable. Only classes do. A concrete class can decide what the vtable has in it, and if you had a "default" implementation, the compiler could stick that in there. Note that the default implementation only can call other member functions within the interface or module-level functions, interfaces cannot access any derived data or members.
Whether such a change would be accepted? No clue.
-Steve
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Chapman | On Thursday, 30 January 2014 at 15:18:12 UTC, John Chapman wrote:
> On Thursday, 30 January 2014 at 14:31:05 UTC, Frustrated wrote:
>> I'm not asking about a work around but if what I am talking about
>> can actually be done(does the vtable support this or can made to
>> support it?)
>
> It would work if you changed the interface to an abstract class.
But then you break the whole usage of interfaces. (multiple
inheritance issue)
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 30 January 2014 at 15:28:24 UTC, Steven
Schveighoffer wrote:
> On Thu, 30 Jan 2014 09:31:05 -0500, Frustrated <c1514843@drdrb.com> wrote:
>
>
>> I'm not asking about a work around but if what I am talking about
>> can actually be done(does the vtable support this or can made to
>> support it?)
>
> Yes. Interfaces have no concrete vtable. Only classes do. A concrete class can decide what the vtable has in it, and if you had a "default" implementation, the compiler could stick that in there. Note that the default implementation only can call other member functions within the interface or module-level functions, interfaces cannot access any derived data or members.
>
> Whether such a change would be accepted? No clue.
>
> -Steve
Basically I see no reason why the compiler can't treat the
interface as a class and allow "default" methods. (it would have
to allow multiple inheritance on that class though)
All it would do is make it easy to provide a default
implementation(more of a static implementation but allows it to
be overriden, which makes it useful).
For example, when creating a design you would no longer have to
specifically create a corresponding class to use for the
interface. You could just provide some default implementations of
everything(throw errors, write stuff, etc...)
I think it would be probably rather easy to do by extending the
vtable to have one lower level, the interface methods, which, in
fact, could use this(so you could have a this in them but only
reference other members of the interface).
Essentially what it boils down to is treating interfaces like
classes that have no fields). To avoid the diamond problem simply
always choose the method that is not from the interface(since it
is "default"), which is done naturally with the vtable.
Of course, maybe this just creates the diamond problem for
interfaces: "which default implementation to use"... which I'm
not sure if it's a problem?
|
January 30, 2014 Re: Interfaces allow member definitions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843@drdrb.com> wrote:
> Essentially what it boils down to is treating interfaces like
> classes that have no fields). To avoid the diamond problem simply
> always choose the method that is not from the interface(since it
> is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation