inheritance - PHP Abstract class return type of child class
How can an abstract class in PHP return the type of the child extending it?
abstract class MyAbstractClass {
public static function fromID($id) : returnType { <======
...
}
}
class MyChildClass extends MyAbstractClass {
public function specificFunctionToThisClass(){
...
}
}
$item = new MyChildClass()->fromID(3);
$item->specificFunctionToThisClass();
The example above is over simplified.
Right now if i call the method fromID(var) in any of the child classes they will return an object of type MyAbstractClass. How can i define the return type of that function in the MyAbstractClass so that no mather what child calls that method it will return the child's class instead of the parent one.
FYI I know i could implement the same function in every children and redirecting the call to the parent but specifying a more specific return type. Long story short my child class are more than 100 and it would be a lot easier defining it only on the parent so that any future changes to the code would not need to be done on every single child class
Answer
Solution:
That returnType
should be MyAbstractClass
, without any implementation (child implements).
This might not be possible, but the child can return an instance of it's own. For dynamic configuration the $model
can have configurations specific to the parent - and the child.
Make everything abstract, with abstract class
and abstract static function
:
abstract class Model {
abstract static function fromArray( array $model ): Model;
abstract static function fromID( int $id ): Model;
}
class LightSettings extends Model {
public function __construct( array|null $config ) {
parent::__construct( $config );
}
static function fromArray( array $model ): LightSettings {
return new LightSettings( $model );
}
static function fromID( int $$preset_id ): LightSettings {
return new LightSettings( null )->load( $preset_id );
}
...
}
The constructor obviously could as well take int $$preset_id
, but it's flexible.
Answer
Solution:
Intended this to be a comment but it is too long for a comment.
Building on Martin Zeitler's answer (sorry Martin, I'm copying your code here below) with an extra static method in the Model class:
abstract class Model {
abstract static function fromArray( array $model ): Model;
abstract static function fromID( int $id ): Model;
// Common stuff for the fromArray factory
protected static function populateFromArray(Model $model, array $modelArray): Model {
// Do whatever is common here
return $model;
}
class LightSettings extends Model {
static function fromArray( array $model ): LightSettings {
return parent::populateFromArray(new LightSettings(), $model);
}
enter code here
static function fromID( int $$preset_id ): LightSettings {
// Similar implementation as in fromArray()
}
...
}
Answer
Solution:
Ok, your question was:
How can an abstract class in PHP return the type of the child extending it?
respectively
How can i define the return type of that function in the MyAbstractClass so that no mather what child calls that method it will return the child's class instead of the parent one.
Short answer is: you can't
Inheritance works top to bottom... under no circumstance can a parent class know it's children.
Imagine a framework. Classes from the framework are intended to be derived. But not the author of the framework writes the inherited class, but some developer who has downloaded that framework and uses it in his/her project. And there can thousands of developers who have done the same, but with different child classes. How would the author of the framework would know all the derived classes? He can't, right?
Source