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