Plain old covariance and contravariance

BCS BCS at pathlink.com
Tue Oct 17 11:30:29 PDT 2006


Hasan Aljudy wrote:
> 
> 
> Reiner Pope wrote:
>>
>> interface Foo
>> {
>>   Foo get();
>>   void set(Bar x);
>> }
>>
>> interface Baz : Foo {}
>>
>> class Bar : Foo
>> {
>>   Bar get() {} // Fine
>>   void set(Foo x) {} // Error, doesn't implement Foo.set
>> }
>>
> 
> I think that's because Bar.set can also accept invalid parameters, such 
> as X, where X extends Foo.
> 
> class X : Foo
> {
>  ...
> }


Why would that be a problem?

Bar.set can only be called from an instance of Foo or Bar. If it is 
called by way of Foo, then the parameter will be a Bar, or something 
derived from Bar (all of which are also Foo s) and thus no problem. If 
it is called by way of Bar, then the parameter will be a Foo (or Foo 
derived), again, no problem.

One potential issue is that class references and interfaces might not be 
treated quite the same (I am currently doing the homework on this one so 
I may be wrong). However even getting rid of that doesn't work.

interface I
{
	void set(B);	// all B's are A's
}

class A{}

class B:A{}

class C:I
{
		// any B can be used
	void set(A a){}
}

I would expect that the issue has something to do with the overload 
resolution rules (it might make the rules more complicated).

<rant type="soapbox">

One fix for this would be to allow explicit mappings.

class C:I
{
	void set(A a){}

	// quick and dirty syntax (not intended for final product)
	alias
	{
		I.set(B) = set(A);
	}
}


This would also allow a single class to implement several (3rd party) 
interface that have methods with the same signature but different semantics.

interface Critic
{
		//returns true if Critic approves of Subject
	bool Opinion(Subject);

		//return a value indicating how much to trust critic
	real Weight();
}

interface PhyObject
{
		//returns height in feet
	real Height();

		//return weight in lb
	real Weight();
}

class Person : PhyObject, Critic
{
	real Weight() // Now what?
}

</rant>



More information about the Digitalmars-d mailing list