On Wed, 07 Jul 2010 17:07:39 -0400, Jonathan M Davis
<[email protected]> wrote:
On Wednesday, July 07, 2010 11:38:09 Robert Jacques wrote:
On Wed, 07 Jul 2010 13:36:16 -0400, Jonathan M Davis
<[email protected]> wrote:
>> Consider the following:
>>
>> interface A { final void foobar() { writeln("A"); } }
>> interface B { final void foobar() { writeln("B"); } }
>>
>> class C : A, B {}
>>
>> void main(string[] args) {
>>
>> C c = new C;
>> c.foobar;
>>
>> }
>>
>> What does foobar print?
>> (This has been filed as bug 4435:
>> http://d.puremagic.com/issues/show_bug.cgi?id=4435)
>
> I believe that per TDPL, you would have to call these with eithe
> c.A.foobar() or
> c.B.foobar() but that c.foobar() is not allowed. If it is allowed at
> present,
> it's definitely a bug. However, it's a bug in the implementation
rather
> than the
> language spec.
>
> - Jonathan M Davis
TDPL Page 215-216, mentions function hijacking of a final function by
the
implementor, which is listed as an error and detected correctly.
Function
hijacking of static functions by the implementor is not handled
correctly.
It also specifically mentions that c.A.foobar() is not the correct, nor
ideal syntax. Indeed, it doesn't currently compile.
That's talking about private final functions in an interface. Read
section 6.9.3
on pages 217 - 218.
1. If you have a method x() which is in two different interfaces and
non-final in
both, then when a class implements both interfaces, it's single method
x()
implements both interfaces x() method simultaneously.
interface A { void x(); }
interface B { void x(); }
class C : A, B { void x() { /* implements both */ } }
void main()
{
C c = new C();
c.x(); // called like this
}
2. If you have a method x() which is two different interfaces and final
in both,
then you can't implement x() in a class which implements both
interfaces. You
also can't call it like c.x() because the compiler wouldn't know which
to call.
You have to specify which interface it's being called for.
interface A { final void x() { /*do something*/ }
interface B { final void x() { /*do something else*/; }
class C : A, B { /* cannot implement x()*/ }
void main()
{
C c = new C();
c.A.x(); // called like this to get A's version
c.B.x(); // called like this to get B's version
}
3. The third case is when the method is final in one interface and not
in the
other. TDPL doesn't say what happens in this case. C wouldn't be able to
implement x() because it would be final in one of the interfaces, but
I'm not
sure if that means the other interface's x() would be used in that case
or if
you couldn't implement both interfaces together. My guess is the latter,
but
TDPL doesn't say.
interface A { final void x() { /*do something*/ }
interface B { void x(); }
class C : A, B { /* Is it legal to implement both interfaces in this
case? */ }
I don't know what exactly dmd does in all cases at this point, but TDPL
is quite
clear that if a class implements two interfaces that both have a final
method
with the same name, then if you're calling that method using the class,
you have
to specify which interface's method you're calling.
- Jonathan M Davis
Thanks for the page numbers. (And I'm suddenly lamenting my slow reading
of TDPL). Anyways, I think the above makes perfect sense, but none of it
is implemented in DMD at this point.