This post is part of a series based on a presentation I gave at Cheppers on March 20, 2019.
PHP quiz #6 - covariance, contravariance and PHPJune 16, 2019
In the previous post we've seen that constructors can be safely overridden. What about functions? Brace yourselves, this is one of my favorite topics.
Will this code throw a warning (PHP 7.1)?
- A Yes
AnswerShow the answer
There are a few cases where functions can be overridden with certain signatures.
iterable is a pseudo-type introduced in PHP 7.1.
It's like an abstract base class for variables that can be iterated with foreach (arrays, Traversable objects).
When a subclass overrides a method of a superclass, it is possible to change its parameter and return types.
Covariance means overriding methods can return more specific types.
array is more specific than an
This is type safe! Think about polymorphism to justify why (pseudocode):
Contravariance means overriding methods can accept less specific parameters.
iterable is less specific than an
This is type safe too! Again, think about polymorphism (pseudocode):
Invariance means the overriding method cannot change the types.
Covariance, contravariance and PHP
PHP does not support covariance/contravariance. It's an invariant language. However, as always, there are a few exceptions:
By now it shouldn't come as a surprise that
iterable, the subject of this blog post is indeed covariant/contravariant.
2. parameter type widening
From PHP 7.2 you can omit parameter types in overriding methods. This is an example of contravariance.
3. return types
If the parent method doesn’t have a return type, it can be specified. This is an example of covariance.
PHP is mostly invariant... for now. But there is progress!
PHP 7.4 is going to add support for real covariance/contravariance (rfc). It will be a great improvement to PHP's type system.