interface and opEquals

Steven Schveighoffer schveiguy at yahoo.com
Tue Nov 6 07:20:51 PST 2007


"Oliver" wrote
> Steven Schveighoffer Wrote:
>
>
> Steve,
>
> thank you for looking into this.

No problem :)

>
>> Your example isn't a good way to demonstrate why this is
>> bad, but imagine if Vi had a base interface...
>
> Unfortunately, I do not understand this. Could you explain a little more, 
> or tell me were i could read up on this?

Here is a better example:

import std.stdio;

class A
{
   int opEquals(A o)
  {
      writefln("A");
      return 0;
   }
}

class B : A
{
   int opEquals(B o)
   {
       writefln("B");
       return 0;
   }
}

void main()
{
   A x = new B;
   A y = new B;
   x == y;
}

This prints "A".

The reason you want to use Object is because the method will override the 
base class' interface.  If you don't do this, you are starting a new method, 
and comparing two base class objects will result in the comparison NOT 
calling your method.

>
>> Having said that, you do not need opEquals to be defined as a method in 
>> your
>> interface, because Object already defines it.  All classes derived from
>> Object will have a valid opEquals.  Perhaps this is why it was not 
>> working
>> for you.
>
>
>> I think this code would work:
>>
>
> The second assert fails. And that is the one i would like to work. I have 
> the impression that it does not work because opEquals does not know what 
> to do with Vi objects.
>
> Then i tried to have opEquals( Object ) in the interface and wanted 
> opEquals ( C1 test ) in the C1 class. But that did not work either. Which 
> kind of makes sense.
>
> hm, i do not really understand this. Any ideas?

Hm... I was not aware that interfaces did not have a base interface, or 
could not be implicitly cast to Object.  This makes sense because if you had 
a base interface that called out opCmp or opEquals, it would not allow 
Object to fulfill that requirement, and therefore you would be required to 
always implement those two functions in the class that implements the 
interface.

I can't figure out how you could have the identified two lines below call 
the same method.  Perhaps this is by design?

interface I
{
  ...
}

class C : I
{
   ...
}

...
I c1 = new C;
I c2 = new C;

//  how can you implement C and I such that the following 2 lines
//  call the same method?
c1 == c2;
cast(Object)c1 == cast(Object)c2;

For now, my recommendation would be to cast the interfaces to Object before 
comparing (i.e. second line above).  Casting to Object should always work 
because an interface should always be able to transform into an Object, 
since the implementation is always a class.  It's ugly, but it should work 
the way you want.

Any D gurus have the answer to this?

-Steve 




More information about the Digitalmars-d-learn mailing list