Differing implementations for a function in two interfaces

Hasan Aljudy hasan.aljudy at gmail.com
Sat Apr 15 17:25:00 PDT 2006


What you want is exactly what polymorphism is designed for. I really 
don't understand what's your problem.

BCS wrote:
> 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