Nikita Popov wrote on 04/02/2015 18:49:
Hi internals!
Currently we do not allow [1] removing a typehint during inheritance. For
example the following code is not valid:
interface A {
public function method(Typehint $param);
}
class B implements A {
public function method($param);
}
// Fatal error: Declaration of B::method() must be compatible with
A::method(Typehint $param)
The above code does *not* constitute an LSP violation, because B::method()
accepts more inputs than A::method(). However we still forbid it.
For those that missed it, or have forgotten, there was a discussion of
covariance and contravariance in November, kicked off by Levi's concerns
over return type hints:
http://grokbase.com/t/php/php-internals/14bstfz0pg/rfc-discussion-return-type-variance-checking
In particular, this Wikipedia article explains the concepts very well
(although once you get into generics it all gets a bit complicated, and
irrelevant to us right now):
http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
<http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29#Covariant_method_return_type>
Removing the typehint is a special case of contravariance, because it
means "accept any type", and parameter contravariance in a nutshell is
"a child implementation must accept at least what the parent accepts,
but may also accept more".
The current situation (invariance) is quite intuitive - the signatures
must match - and full contravariance can be explained fairly easily -
"B:method must accept all values accepted by A::method". My worry is
that people won't understand why this particular special case is
allowed, and may think PHP is just letting them be sloppy and remove
other people's type hints.
The other thing to consider is whether the same special case should be
added (in reverse) to return type hints - a sub-class could *introduce*
a return type hint, as long as the parent class did not already declare one.
Regards,
--
Rowan Collins
[IMSoP]