Abstract Classes vs Interfaces
Robert Jacques
sandford at jhu.edu
Wed Jul 7 16:41:04 PDT 2010
On Wed, 07 Jul 2010 17:07:39 -0400, Jonathan M Davis
<jmdavisprog at gmail.com> wrote:
> On Wednesday, July 07, 2010 11:38:09 Robert Jacques wrote:
>> On Wed, 07 Jul 2010 13:36:16 -0400, Jonathan M Davis
>>
>> <jmdavisprog at gmail.com> 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.
More information about the Digitalmars-d
mailing list