D interface bug?

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Mar 30 00:06:23 UTC 2019


On Fri, Mar 29, 2019 at 11:44:35PM +0000, Alex via Digitalmars-d-learn wrote:
> interface iBase
> {
> 	iBase fooBase(iBase);
> }
> 
> 
> class cBase : iBase
> {
> 	cBase fooBase(cBase c) { return c; }	
> 
> }
> 
> cBase.fooBase should be a valid override of iBase.fooBase because they
> are the same type! cBase is a super type so it contains everything
> iBase contains and maybe more.

No, that's wrong. Consider this:

	class cBase : iBase
	{
		int x;
		cBase fooBase(cBase c) { return (x==1) ? c : null; }
	}

	class dBase : iBase
	{
		string y;
		dBase fooBase(dBase c) { return (y=="a") ? c : null; }
	}

	iBase intf = new cBase;
	dBase dobj = new dBase;
	dobj.fooBase(intf); // oops: intf.y doesn't exist!

I.e., it's invalid for dBase.fooBase to override the interface method.

The parameter type of fooBase must be the interface type or a
super-interface thereof.  For a class C to inherit from an interface X
means that C contains a subset of all possible objects that X might
refer to.  Therefore, if a method takes a parameter of type C, it
*cannot* be passed an argument of type X, since the actual object might
be outside the subset that C includes. IOW, such a method cannot be
covariant with a method that takes X as a parameter.


> There should be no reason why the compiler can't figure this out. It's
> a very simple rule.
> 
> Any time the user calls iBase.fooBase it can be replaced with
> cBase.fooBase so it should not compromise any code to go ahead and
> accept it as a proper override.
[...]

Nope.  The user can call iBase.fooBase, passing it an instance of a
different class that also implements iBase but does not inherit from
cBase.  Then cBase.fooBase would receive an argument of incompatible
type.


T

-- 
"A man's wife has more power over him than the state has." -- Ralph Emerson


More information about the Digitalmars-d-learn mailing list