2 ms·
I don't quite know what point this feature came to be, but in Java it's now compiler-correct for subclasses to declare their overrides as returning a more preci
by paulmd 3y ago
I don't quite know what point this feature came to be, but in Java it's now compiler-correct for subclasses to declare their overrides as returning a more precise type than the superclass, as long as it doesn't disagree with the superclass.
The place I've bumped into this is the "self"/"builder" pattern of setter. So for example if you have the superclass method:
abstract public Shape setArea(Number area);
it's absolutely correct for other interfaces to override it with more precise definitions that they expect their members to obey:
@Override abstract public Quadrilateral setArea(Number area);
@Override public Square setArea(Number area) { this.area = area; return this; }
The downside here is that interfaces and classes have to override all such methods with their own implementation returning the proper type, even if it's just { super.setArea(area); return this } otherwise the superclass's looser definition will be used. For example if you don't override the area method then this doesn't work:
//compiler error: method setSides is unknown for class Shape
new Square().setArea(area).setSides(sides)
But if subclasses override all their methods, for example if Square overrides the setArea method with one returning Square, the above example works.
Obviously, again, only works if you know the instance you're being passed is a Quadrilateral or a Square, but if you don't know that you are reduced to casting based on some kind of list or handler.