www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - interface not able to use functions from base classes??

reply =?UTF-8?B?IsOYaXZpbmQi?= <oivind.loe gmail.com> writes:
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
next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
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
http://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
prev sibling parent reply "Todd VanderVeen" <tdvanderveen gmail.com> writes:
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
parent reply =?UTF-8?B?IsOYaXZpbmQi?= <oivind.loe gmail.com> writes:
 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
next sibling parent "Todd VanderVeen" <tdvanderveen gmail.com> writes:
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
prev sibling parent "Todd VanderVeen" <tdvanderveen gmail.com> writes:
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