A child class overriding a method had to declare exactly the parent’s return type, so an abstract repository could not promise that each implementation returns its own entity.
abstract class Repository
{
abstract public function find(int $id): Entity;
}
final class Orders extends Repository
{
public function find(int $id): Order { /* ... */ } // 7.4: allowed
}
// and the mirror image: a child may accept a WIDER parameter type
Callers of Orders::find now get an Order rather than an Entity, so the downcast and its instanceof disappear from every call site — and the analyser can see it, which is where most of the value is. The rule is substitutability: return something more specific, accept something more general, never the reverse. Interfaces get the same treatment, which is what makes a self-typed factory expressible.