Comment #0 by andrej.mitrovich — 2010-08-15T10:32:38Z
Code on 2.048:
import std.stdio;
interface Timer
{
final void run() { writeln("Timer.run()"); };
}
interface Application
{
final void run() { writeln("Application.run()"); };
}
class TimedApp : Timer, Application
{
}
import std.stdio;
void main()
{
auto app = new TimedApp;
app.Timer.run(); // error, no Timer property
app.Application.run(); // error, no Application property
app.run(); // This would call Timer.run() if the two calls
// above were commented out
}
The comments state what happens.
Note that if I changed the order of the TimedApp signature like so:
class TimedApp : Application, Timer
then the Application's run() method would be called instead of Timer's in the app.run() call.
Comment #1 by andrej.mitrovich — 2010-08-15T12:04:34Z
Comment from Lukasz Wrzosek
>This:
> app.Timer.run(); // error, no Timer property
> app.Application.run(); // error, no Application property
>
>probably should be:
> (cast(Timer)app).run();
> (cast(Application)app).run();
>
>But app.run() is still ambiguous - should not compile.
I don't see why I would need a cast. I can explicitly call methods from inherited classes, like so:
import std.stdio;
class Base
{
void test() { writeln("Base.test()"); };
}
class Derived : Base
{
override void test() { writeln("Derived.test()");}
}
class SecondDerived : Derived
{
}
void main()
{
auto var = new SecondDerived;
var.Base.test(); // calls Base.test()
var.Derived.test(); // calls Derived.test()
}
So why shouldn't I be able to do the same with interfaces? TDPL allows it, I think it should be allowed in DMD.
Comment #2 by bugzilla — 2010-08-16T00:05:38Z
I don't have TDPL in front of me right now, but I, too, seem to remember that this should be allowed. Raising the priority of this.
Comment #3 by k.hanazuki — 2011-10-25T12:38:15Z
*** Issue 6680 has been marked as a duplicate of this issue. ***
Comment #4 by k.hara.pg — 2011-12-24T02:18:52Z
Patch for app.Timer.run() / app.Application.run():
https://github.com/D-Programming-Language/dmd/pull/578
----
(In reply to comment #0)
> Note that if I changed the order of the TimedApp signature like so:
>
> class TimedApp : Application, Timer
>
> then the Application's run() method would be called instead of Timer's in the
> app.run() call.
I think the behavior is correct, because name lookup is depth-first.
Then app.run() depends on the order of derived bases.