Code:
--------------------
interface Marker {}
interface Foo { void foo(); }
interface FooMarked : Foo, Marker {}
interface MarkedFoo : Marker, Foo {}
class Base : Foo { override void foo() {} }
class Derived1 : Base, FooMarked {} // Inherit Base.foo
class Derived2 : Base, MarkedFoo {} // Error!
void main() {}
--------------------
Compiler output:
--------------------
main.d(10): Error: class main.Derived2 interface function 'void foo()' is not implemented
--------------------
The interface `Foo` in `Derived1` is silently inherited from `Base` while the documentation [1] says: "A reimplemented interface must implement all the interface functions, it does not inherit them from a super class".
Using swapped base interfaces in `Derived2` causes compilation error as expected.
May be related to issue 15591.
[1] https://dlang.org/spec/interface.html
Comment #1 by razvan.nitu1305 — 2018-01-12T13:25:21Z
FWIW the Java code works without requiring the additional implementation:
interface Marker {}
interface Foo { void foo(); }
interface FooMarked extends Foo, Marker {}
interface MarkedFoo extends Marker, Foo {}
class Base implements Foo { public void foo() {} }
class Derived1 extends Base implements FooMarked {} // Inherit Base.foo
class Derived2 extends Base implements MarkedFoo {} // Inherit Base.foo
Comment #3 by r.sagitario — 2018-01-15T19:02:14Z
I always considered it a great relief that you don't have to reimplement common interfaces. Otherwise COM-programming would be much more verbose. What's the reasoning to disallow it?
The old samples in dmd/samples also assume that IUnknown doesn't have to be reimplemented.
Comment #4 by andrei — 2018-01-15T19:23:29Z
The following C++ equivalent does require the additional implementation (uncomment code to get it to compile):
--------------------
class Marker {};
class Foo { public: virtual void foo() = 0; };
class FooMarked : public Foo, public Marker {};
class MarkedFoo : public Marker, public Foo {};
class Base : public Foo { virtual void foo() {} };
class Derived1 : public Base, public FooMarked {
//virtual void foo() {}
};
class Derived2 : public Base, public MarkedFoo {
//virtual void foo() {}
};
int main() {
auto d1 = new Derived1;
auto d2 = new Derived2;
}
--------------------
However, this other code, which arguably is closer in spirit, does work:
--------------------
class Marker {};
class Foo { public: virtual void foo() = 0; };
class FooMarked : virtual public Foo, public Marker {};
class MarkedFoo : public Marker, virtual public Foo {};
class Base : virtual public Foo { virtual void foo() {} };
class Derived1 : public Base, public FooMarked {};
class Derived2 : public Base, public MarkedFoo {};
int main() {
auto d1 = new Derived1;
auto d2 = new Derived2;
}
--------------------
Comment #5 by robert.schadek — 2024-12-13T18:52:22Z