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