Rant after trying Rust a bit

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 23 08:38:51 PDT 2015


On Thursday, 23 July 2015 at 15:20:36 UTC, jmh530 wrote:
> It definitely seems weird that this behavior isn't
> mentioned anywhere.

It isn't really expanded upon, but the : Interfaces at the top 
here tells you can inherit them:

http://dlang.org/interface.html

It doesn't show an example in the text of an interface extending 
another interface, but it does say "interfaces can be inherited".

> Also, the use of static* or final methods in the interface can 
> allow default implementations of methods.

Eh sort of but not really. static and final methods cannot be 
overridden in the virtual sense.

interface Foo {
         final void foo() { writeln("foo"); }
}
class Bar : Foo {
         override void foo() { writeln("foo from bar"); }
}


b.d(8): Error: function b.Bar.foo does not override any function, 
did you mean
o override 'b.Foo.foo'?
b.d(8): Error: function b.Bar.foo cannot override final function 
Foo.b.Foo.foo



Static is similar, change those finals to static and you get:


b.d(8): Error: function b.Bar.foo cannot override a non-virtual 
function


Take override off and it compiles... but is statically dispatched:

         Foo bar = new Bar();
         bar.foo(); // calls the version from the interface

         Bar bar = new Bar();
         bar.foo(); // calls the version from the class



That's the main thing with interfaces: you are supposed to get 
the overridden method when you call it through the base, but that 
only happens if it is virtual - neither final nor static. And 
those cannot have default implementations in a D interface, only 
in a class.

> The tricky part is that I had been using something like final 
> foo() { } instead of final void foo() { }. For some reason you 
> can override the first, but not the second.


You just defined a template by skipping the return type... 
templates are allowed in D interfaces and classes, but are always 
implicitly final, and thus get the behavior above - if you call 
it through the interface, you get a different func than calling 
it through the class.




BTW you can also check interface conversion for objects in a 
template function and get static dispatch that way... sort of:

void something(T : Foo)(T bar) {
         bar.foo();
}
void main() {
         Foo bar = new Bar();  // explicitly using the interface
         something(bar); // leads to this calling "foo"

         // but if you did "auto bar = new Bar();" or "Bar bar"
        // it would call "foo from bar"
}


More information about the Digitalmars-d mailing list