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