digitalmars.D - interface not able to use functions from base classes??
- =?UTF-8?B?IsOYaXZpbmQi?= (18/18) Dec 24 2013 Why doesn't this work:
- Maxim Fomin (5/23) Dec 25 2013 http://dlang.org/interface.html
- Todd VanderVeen (28/46) Dec 25 2013 I presume your intent is to have B inherit the implementation
- =?UTF-8?B?IsOYaXZpbmQi?= (14/24) Dec 25 2013 My case is a single base class 'Base' and multiple subclasses
- Todd VanderVeen (1/25) Dec 25 2013
- Todd VanderVeen (51/51) Dec 25 2013 To try and answer your original question more specifically. You
Why doesn't this work: ---- class A { int f(int x) { return x; } } interface I { int f(int x); } class B : A, I { } void main() {} ---- I get the following error with DMD 2.064.2: /d122/f338.d(11): Error: class f338.B interface function 'int f(int x)' is not implemented
Dec 24 2013
On Wednesday, 25 December 2013 at 07:40:03 UTC, Øivind wrote:Why doesn't this work: ---- class A { int f(int x) { return x; } } interface I { int f(int x); } class B : A, I { } void main() {} ---- I get the following error with DMD 2.064.2: /d122/f338.d(11): Error: class f338.B interface function 'int f(int x)' is not implementedhttp://dlang.org/interface.html Strictly speaking B does not implement function and inhereting function from base class is not the same as implementing the function.
Dec 25 2013
I presume your intent is to have B inherit the implementation from A. There are two options. If you control class A and its appropriate to declare the interface there, you can declare that A implements I and have B simply inherit it from A. class A : I { int f(int x) { return x; } } interface I { int f(int x); } class B : A { } void main() { writeln(new B().f(7)); } If you only intend to introduce the interface on B, you still need to provide an implementation for I, either voluntarily overriding A or providing an alternate implementation to the virtual interface. To do the former, you can do the following: class A { int f(int x) { return x; } } interface I { int f(int x); } class B : A, I { override int f(int x) { return super.f(x); } } void main() { writeln(new B().f(7)); } On Wednesday, 25 December 2013 at 07:40:03 UTC, Øivind wrote:Why doesn't this work: ---- class A { int f(int x) { return x; } } interface I { int f(int x); } class B : A, I { } void main() {} ---- I get the following error with DMD 2.064.2: /d122/f338.d(11): Error: class f338.B interface function 'int f(int x)' is not implemented
Dec 25 2013
Strictly speaking B does not implement function and inhereting function from base class is not the same as implementing the function.Yes, but it really seems like this is something that could and should work..If you control class A and its appropriate to declare the interface there, you can declare that A implements I and have B simply inherit it from A.If you only intend to introduce the interface on B, you still need to provide an implementation for I, either voluntarily overriding A or providing an alternate implementation to the virtual interface.My case is a single base class 'Base' and multiple subclasses grouped under different interfaces.. e.g. class Base {} class A : Base, I0 {} class B : Base, I0 {} class C : Base, I1 {} I need access to functionality provided in Base through the interfaces I0, I1, ... It really sucks having to re-implement this functionality in all the subclasses, e.g. A, B, C.. Seems very unnecessary. I finally implemented this using a mixin template, so the actual code for it isn't that big, but still..
Dec 25 2013
On Wednesday, 25 December 2013 at 09:44:32 UTC, Øivind wrote:Strictly speaking B does not implement function and inhereting function from base class is not the same as implementing the function.Yes, but it really seems like this is something that could and should work..If you control class A and its appropriate to declare the interface there, you can declare that A implements I and have B simply inherit it from A.If you only intend to introduce the interface on B, you still need to provide an implementation for I, either voluntarily overriding A or providing an alternate implementation to the virtual interface.My case is a single base class 'Base' and multiple subclasses grouped under different interfaces.. e.g. class Base {} class A : Base, I0 {} class B : Base, I0 {} class C : Base, I1 {} I need access to functionality provided in Base through the interfaces I0, I1, ... It really sucks having to re-implement this functionality in all the subclasses, e.g. A, B, C.. Seems very unnecessary. I finally implemented this using a mixin template, so the actual code for it isn't that big, but still..
Dec 25 2013
To try and answer your original question more specifically. You have told the compiler that B derives from A inheriting method f. You have also said that B implements a virtual interface I. I does not have an implementation, despite sharing a common signature with f. If you just wanted f, there is no need to declare that it derives from I. If it needs to be both, but you want leverage A's implementation. Then this does the trick: override int f(int x) { return super.f(x); } providing an implementation for I wired to f. I think you are asking why doesn't the compiler assume I's implementation from A. Overriding a method in D is voluntary. The rationale is covered well in Andrei's book in section 6.4.4 if you have it. As you have declared a virtual method with the same signature, an implementation is required. As you have not provided one, by overriding the implementation found in A, the compiler complains. ---- It is not clear whether you are wanting to decorate existing implementations with interfaces or decompose a monolithic base class. If the former, simply introduce all of the interfaces on the Base class. No wiring is then required to the subclasses. You get what you have now without the duplication and the subclasses can still vary the implementations if desired. class Base : I0, I1, I2 As written, you are introducing numerous variants of the Base each with one additional interface defined. If you want to define several new types with subsets of Base functionality cleanly hidden behind the interfaces, the proxy pattern may serve your purpose better. class Base { int m0() { return 0; } int m1() { return 1; } int m2() { return 2; } } interface I0 { int m0(); } interface I1 { int m1(); } interface I2 { int m1(); } class A : I0 { private Base hidden = new Base(); int m0() { return hidden.m0(); } } class B : I1 { private Base hidden = new Base(); int m1() { return hidden.m1(); } } void main() { writeln(new A().m0()); writeln(new A().m1()); } If you inherited a 'god class', you will need to do some work to undo it.
Dec 25 2013