PHP 7.4, released November 2019 has improved type variance.
The code from the question remains invalid:
interface Item { // some methods here}interface SuperItem extends Item { // some extra methods here, not defined in Item}interface Collection { public function add(Item $item); // more methods here}interface SuperCollection extends Collection { public function add(SuperItem $item); // This will still be a compile error // more methods here that "override" the Collection methods like "add()" does}
Because the Collection
interface guarantees that anything that implements it can accept any object of type Item
as the parameter of add
.
However, the following code is valid in PHP 7.4:
interface Item { // some methods here}interface SuperItem extends Item { // some extra methods here, not defined in Item}interface Collection { public function add(SuperItem $item); // more methods here}interface SuperCollection extends Collection { public function add(Item $item); // no problem // more methods here that "override" the Collection methods like "add()" does}
In this case Collection
guarantees that that it can accept any SuperItem
. Since all SuperItem
s are Item
s, SuperCollection
also makes this guarantee, while also guaranteeing that it can accept any other type of Item
. This is known as a Contravariant method parameter type.
There is a limited form of type variance in earlier versions of PHP. Assuming other interfaces are as in the question, the SuperCollection
may be defined as:
interface SuperCollection extends Collection { public function add($item); // no problem // more methods here that "override" the Collection methods like "add()" does}
This can be interpreted as meaning any value whatsoever may be passed to the add
method. That of course includes all Item
s, so this is still type safe, or it can be interpreted as meaning that an unspecified class of values, generally documented as mixed
may be passed and the programmer needs to use other knowledge of exactly what can work with the function.