In PHP I have an abstract class that looks like this (simplified):
abstract class MiClase {
protected $id = "";
protected $titulo = "";
function __construct($titulo) {
$this->id = strtolower($titulo);
$this->titulo = $titulo;
}
abstract function render();
}
And then a child class that inherits from that:
class MiSubClase extends MiClase {
function __construct($titulo) {
parent::__construct($titulo);
}
function render() {
echo "$this->id: $this->titulo";
}
}
I want to add a second constructor to the abstract class in which an id can be passed in addition to the title, but in PHP there is no function overloading by parameters. Searching the Internet, I found a post on Stack Overflow in English where what is suggested is to create a static function that creates and returns an instance of the object itself and does the "second constructor" functions, something like this:
static function crea($id, $titulo) {
$instancia = new self($titulo);
$this->id = $id;
return $instancia;
}
That method works fine on "normal" classes, but it doesn't work on abstract classes like this one and I get the following error when I do $miclase = MiClase::crea("id", "titulo");
:
Exception: Cannot instantiate abstract class MyClass
that occurs on the line where I do $instancia = new self("titulo")
, and that makes sense because it would be trying to instantiate the class itself, which is abstract, which is not allowed.
How then could one create multiple constructors in an abstract class in PHP?
A possible solution would be to use static bindings at runtime ( Late Static Bindings , in English). Static late bindings were introduced as of PHP 5.3.0 and can be used to reference the called class in a static inheritance context. From the PHP documentation (emphasis mine):
In the comments section of the PHP documentation, mhh1422 lays out an example similar to the case in the question, with a static method used to create a factory method :
So the solution is as simple as changing the
new self($titulo)
tonew static($titulo)
. So the code would look like this and the error no longer occurs:Which would then be called like this from the child class:
The answer is simple: no way . Moreover, an abstract class must not have a constructor, because it is not a class to be instantiated.
The reference is very clear in the PHP Manual :
I leave this reference , which will help, starting from real life cases, to understand the true meaning of abstract classes in PHP, and I advocate that there is (if it does not already exist), a good explanation about it on Stackoverflow in Spanish.
The overload as such does not exist in PHP but we can emulate part of it using the functions
func_get_args()
,func_num_args()
andcall_user_func_array()
, the basic idea is to create a constructor that calls one or another function depending on the number of argumentsOur abstract class
Class that calls
parent::__construct
with a parameterClass that calls
parent::__construct
with two parametersExample:
In this way we can create the constructors we need with the number of parameters we need, we only have to use the number of parameters to define the name of the fake constructor, I hope you get the idea.