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

Reply via email to