Differing implementations for a function in two interfaces
BCS
BCS_member at pathlink.com
Sat Apr 15 17:01:44 PDT 2006
Two issues with this solution:
1> the solution does not use interfaces. The assumption I was working under is
that I am given a pair of interfaces that both have a function with the same
name and parameters but imply different actions. This is more or less trivial to
get around, add a constructor to the CA and CB classes that stores the object to
a member.
2> This solution breaks down in any but the most trial of cases, consider:
interface I {int get();}
interface J {int get();}
class C { int i; }
class CI : I
{
C c;
this(C cv) { c = cv; }
int get(){ return c.i + 1; }
}
class CJ : J
{
C c;
this(C cv) { c = cv; }
int get(){ return c.i + 2; }
}
// this works fine until we derive from C
class D
{
int get(){ return (i != 4)?54:42; }// must be override get in I
int get(){ return 4; }// must be override get in J
}
One solution is to make CI and CJ call C.getI and C.getJ from c, but that
requires another level or two of indirection that can be avoided with a syntax
that would allow us to dictate the mapping of class methods to interface methods
Basically, yes you can get around these issues without changing D but the
solution is substantially inferior to what could be available with some small
changes.
In article <e1rm6d$7u1$2 at digitaldaemon.com>, Hasan Aljudy says...
>
>Hasan Aljudy wrote:
>> BCS wrote:
>>> In article <e1riem$3jd$1 at digitaldaemon.com>, Hasan Aljudy says...
>>>
>>>> I didn't read/undertstand your entire post, but I think what you're
>>>> trying to achieve here can already be achieved through polymorphism.
>>>>
>>>> I think you just need to redeisgn the classes a little bit.
>>>
>>> I don't think that would (always) work. Consider the following:
>>>
>>> interface IA
>>> {
>>> int get();
>>> }
>>>
>>> interface IB
>>> {
>>> int get();
>>> }
>>>
>>> class C : IA, IB
>>> {
>>> public int i;
>>> // illegal but ...
>>> int get() { return i+1; } // get for IA
>>> int get() { return i+2; } // get for IB
>>> }
>>>
>>> void main()
>>> {
>>> auto obj = new C;
>>> IA a = obj;
>>> IB b = obj;
>>>
>>> obj.i = 0;
>>> writef(a.get, \n); // should print 1
>>> writef(b.get, \n); // should print 2
>>>
>>> obj.i = 2;
>>> writef(a.get, \n); // should print 3
>>> writef(b.get, \n); // should print 4
>>>
>>> }
>>>
>>> Both "a" and "b" are actually pointing to obj but calls to "get" using
>>> them are
>>> supposed to differ. Some types of this problem could be handled by
>>> deriving
>>> classes from C but not when the interfaces must actually be dealing
>>> with the
>>> same object.
>>>
>>> Cases like this could really happen if someone needs to implement two
>>> interfaces
>>> from different libraries in the same class.
>>
>> I know, I'm saying, you can do this using polymorphism, along with a
>> redesign, invloving decoupling the get method from the C class.
>>
>> class C
>> {
>> protected int i;
>> }
>>
>> abstract class CGetter
>> {
>> abstract int get( C c );
>> }
>>
>> class CA : CGetter
>> {
>> int get( C c )
>> {
>> return c.i + 1;
>> }
>> }
>>
>> class CB : CGetter
>> {
>> int get( C c )
>> {
>> return c.i + 2;
>> }
>> }
>>
>> void main()
>> {
>> auto obj = new C;
>> CA a = new CA;
>> CB b = new CB;
>>
>> obj.i = 0;
>>
>> writefln(a.get(c)); // should print 1
>> writefln(b.get(c)); // should print 2
>>
>> obj.i = 2;
>> writefln(a.get(c)); // should print 3
>> writefln(b.get(c)); // should print 4
>> }
>>
>>
>>
>> A bit more complicated (for this simple example), but you're doing the
>> same thing: creating new entries in a vtable, to choose different
>> functions at runtime.
>>
>
>ouch, typo, replace a.get(c) with a.get(obj)
>
> obj.i = 0;
>
> writefln(a.get(obj)); // should print 1
> writefln(b.get(obj)); // should print 2
>
> obj.i = 2;
> writefln(a.get(obj)); // should print 3
> writefln(b.get(obj)); // should print 4
More information about the Digitalmars-d-learn
mailing list