Req #71825 [Com]: PHP does not allow weaker parameter signature in child interface/class.
| From: | jpauli@php.net | Date: | Mon, 04 Apr 2016 14:32:51 +0000 |
| Subject: | Req #71825 [Com]: PHP does not allow weaker parameter signature in child interface/class. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-200347@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=71825&edit=1
ID: 71825
Comment by: jpauli@php.net
Reported by: andreas at dqxtech dot net
Summary: PHP does not allow weaker parameter signature in
child interface/class.
Status: Suspended
Type: Feature/Change Request
Package: Class/Object related
Operating System: Linux
PHP Version: 7.0.4
Assigned To: krakjoe
Block user comment: N
Private report: N
New Comment:
Yes, Liskov "widening" has been so many times debated so far, with no consensus about it.
We'll need to reopen the discussion through a RFC for it
Previous Comments:
------------------------------------------------------------------------
[2016-03-26 21:31:12] krakjoe@php.net
For this kind of change, an RFC is required.
Please see: https://wiki.php.net/rfc/howto
------------------------------------------------------------------------
[2016-03-14 22:54:24] andreas at dqxtech dot net
https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Contravariant_method_argument_type
------------------------------------------------------------------------
[2016-03-14 22:32:46] andreas at dqxtech dot net
Description:
------------
The Liskov substitution principle requires that any child thingy can replace the parent thingy. It
does not require the opposite.
A weaker signature should be ok with the LSP.
Unfortunately, in PHP, it is not.
Demo: https://3v4l.org/MX0Cb
See also http://stackoverflow.com/questions/13423494/why-is-overriding-method-parameters-a-violation-of-strict-standards-in-php#comment18345860_13423625
"if the parameters are contravariant then the types are respected. If PHP was pure OO then
there would be no problem, since Array would be narrower than Object (assuming that no type in the
declaration means any object)."
One can always dream..
And, just saying: Others are making arguments about overloading. I think this is really a different
story and does not apply here. To overload, you will use a narrower signature, so that the version
of the method is only applied in some cases, not all. On the other hand, the broader / weaker
signature always includes all cases of the parent, so this version will always be used.
Test script:
---------------
interface I {
function foo(J $j);
}
interface J extends I {
function foo(I $i);
}
Expected result:
----------------
Compile just fine.
Actual result:
--------------
"Fatal error: Declaration of J::foo() must be compatible with that of I::foo()"
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=71825&edit=1