I guess that the "... must be compatible with ..." is in place to enforce Liskov Substitution Principle. But I am not sure this is what LSP says?
I have a code like this:
class General
{
public static function create(): General
{
return new static;
}
public function doSomething()
{
echo get_class($this) . ' speaking!' . PHP_EOL;
}
}
class Specific extends General
{
public static function create(): Specific
{
return parent::create();
}
}
function doSomething(General $object)
{
$object->doSomething();
}
doSomething(General::create());
doSomething(Specific::create());
Which produces:
PHP Fatal error: Declaration of Specific::create(): Specific must be compatible with General::create(): General in ...
The LSP is often cited as:
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
And this is not violated here as far as I understand. So what is wrong here? Is it some special restriction that doesn't have anything to do with LSP? Is it a bug in PHP? Am I doing something wrong without knowing?
UPDATE: I found this thread (Parameter type covariance in specializations). I understand and fully agree that the example there violates LSP. But my situation is different (reverse in fact).