Assume I have three classes like so.
abstract class A {
abstract protected function doSomething($object): array;
}
class B extends A {
protected functi
You can't without implementing it yourself in similar way than in your example.
PHP support for covariance and contravariance is clearly defined:
Covariance allows a child's method to return a more specific type than the return type of its parent's method. Whereas, contravariance allows a parameter type to be less specific in a child method, than that of its parent.
If a child class were capable of having stricter parameter requirements than its parent or interface, this would lead to broken expectations.
For example: let's say that you have the following:
abstract class AbstractParam{}
class ParamOne extends AbstractParam{}
class ParamTwo extends AbstractParam{}
class ParamThree extends AbstractParam{}
abstract class AbstractService {
abstract public function foo(AbstractParam $bar);
}
Any time you would need to use an implementation of this service, you would do so with the assurance that passing any valid instance of AbstractParam
to foo()
would be legal. The method signature is clearly communicating this.
If I could change this on inheritance/implementation, and suddenly I could change foo()
signature to:
public function foo(ParamOne $bar)
The contract would be broken, and you couldn't depend on AbstractService
safely, since there would be no longer possible to pass any AbstractParam
instance to foo()
, thus violating the LSP in the process: You could no longer substitute objects of the base class with objects that belong to a subtype of that base object while maintaining correctness.
The approach in your question would work, but I don't think it's a great design for the above reasons. If you really must go that way, simply remove the type hint from method definition:
abstract class AbstractService {
abstract public function foo($bar);
}
class ConcreteService extends AbstractService {
public function foo($bar) {}
}
But it's probably better to rethink why you actually need this, and try to retain type-safety.