interfaces and contracts - new pattern
Adam D. Ruppe
destructionator at gmail.com
Tue Dec 3 15:25:19 UTC 2019
On Tuesday, 3 December 2019 at 15:12:46 UTC, Ola Fosheim Grøstad
wrote:
> But I was thinking of contravariant/covariant parameters on
> virtual functions.
those too. I mostly use it with things like a clone method:
interface Cloneable {
Cloneable clone();
}
class MyClass : Cloneable {
override MyClass clone() { return new Myclass(); }
}
That is fairly intuitive for return values - MyClass is an
instance of the interface so of course you should be able to
return it! It just lets you specialize.
On the parameters side it is a little more confusing, but it
still makes sense:
abstract class Generic {
void generic(Generic g);
}
class Specialized : Generic {
override void generic(Specialized g) {}
}
There you can see the obvious problem:
Generic g = new Specialized();
Generic other = new SomethingElse();
g.generic(other); // uh oh, interface allows it but
specialization doesn't
But that's also why you can loosen.
class Specialized : Generic {
override void generic(Object g) {}
}
since Generic implicitly casts back to Object, it is clear
anything from the interface can also go to the child, so you're
fine.
And if you do call the `super.generic`, you get the explicit cast
requirement which is OK, since it happens in the implementation's
body.
And then contracts follow the same rules...
It does make sense if you think about it, just it is weird if you
don't.
More information about the Digitalmars-d-announce
mailing list