Req #72208 [Wfx]: Covariant parameter types should be supported
| From: | bwoebi@php.net | Date: | Wed, 18 May 2016 12:31:08 +0000 |
| Subject: | Req #72208 [Wfx]: Covariant parameter types should be supported | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-201181@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72208&edit=1
ID: 72208
Updated by: bwoebi@php.net
Reported by: mbrowne83 at gmail dot com
Summary: Covariant parameter types should be supported
Status: Wont fix
Type: Feature/Change Request
Package: Class/Object related
Operating System: Ubuntu 14.04.4 LTS
PHP Version: 7.0.6
Block user comment: N
Private report: N
New Comment:
Contravariant parameter types are something to be considered and already are ⦠but they have
their own problems (regarding binding-time verification of the type ⦠as classes are currently
not autoloaded when just a typehint is encountered, so you cannot check whether there's a
relation between two differently named types or not.)
Previous Comments:
------------------------------------------------------------------------
[2016-05-12 14:49:20] mbrowne83 at gmail dot com
Sorry, I was confused. I noticed that contravariant parameter types are also not supported, but I
imagine that was a design decision rather than an oversight. Thank you.
------------------------------------------------------------------------
[2016-05-12 14:30:05] requinix@php.net
Oh, and the entry goes on to mention that generics/templating can help to address the use case. That
feature is being considered: https://wiki.php.net/rfc/generics
------------------------------------------------------------------------
[2016-05-12 14:27:13] requinix@php.net
How much of that Wikipedia entry did you read?
1. As it says, Eiffel is "[unique] among mainstream languages" for its support for
covariant parameters.
2. The code does not obey LSP because of exactly what the entry points out: CatShelter needs to
support everything that AnimalShelter does. By restricting the parameter to only Cat objects, it
*breaks* LSP "which states that objects of subclasses should always be less restricted than
objects of their superclass".
function PutDogInShelter(AnimalShelter $shelter) {
$dog = new Dog(); // class Dog extends Animal
$shelter->putAnimal($dog);
}
The above code needs to work with all AnimalShelter-type objects, however it will not work with
CatShelters.
------------------------------------------------------------------------
[2016-05-12 13:50:28] mbrowne83 at gmail dot com
Description:
------------
It seems that PHP does not support covariant parameter types. It should be possible to override a
base class method and make its parameter type more specific. In the code example, the warning
message is erroneous (or at least arbitrary) because the code does in fact conform to the Liskov
Substitution Principle and is valid OOP.
Test script:
---------------
//example use case from https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Covariant_method_return_type
class Animal {}
class Cat extends Animal {}
class AnimalShelter {
function putAnimal(Animal $a) {}
}
class CatShelter extends AnimalShelter {
function putAnimal(Cat $c) {}
}
Expected result:
----------------
No output
Actual result:
--------------
Warning: Declaration of CatShelter::putAnimal(Cat $c) should be compatible with
AnimalShelter::putAnimal(Animal $a) in /vagrant/test.php on line 14
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72208&edit=1