When you extend a class, all the methods on that class exist on the child class by default, including "magic" methods like __construct
.
So when you write this:
class Base {
protected $var;
public function __construct($var){
$this->var = $var;
}
}
class ChildA extends Base {
public function handle(){
echo $this->var;
}
}
Your child class actually looks something like this:
class ChildA extends Base {
// Inherited property from Base class
protected $var;
// Inherited method from Base class
public function __construct($var){
$this->var = $var;
}
// New method in this class
public function handle(){
echo $this->var;
}
}
This is a slight simplification, as we'll see below, but it explains what happens in your example:
$base = new Base(10);
$base
is an instance of the Base
class; it is completely separate from any other instance of that class, and from any instance of the ChildA
class.
(new ChildA())->handle();
This attempts to run the __construct
method in the ChildA
class; the copy of that method inherited from Base
requires an argument, but you didn't supply one, so you get an error. It is expecting you to call it like this:
(new ChildA(10))->handle();
If we define __construct
directly in the child class, we can give it a different number of arguments:
class ChildB extends Base {
public function __construct() {
// Do nothing
}
public function handle(){
echo $this->var;
}
}
(new ChildB())->handle();
But now we have a different problem: the logic in the Base
class isn't running, so $this->var
is never set to anything.
This is where I over-simplified things above. In reality, the parent __construct
method and child __construct
method both exist, they just "hide" each other. You can access the parent copy with the syntax parent::method
.
So you can make a child class, with a constructor which takes no arguments, and when that constructor is run, run the base constructor with a hard-coded value of 10
:
class ChildC extends Base {
public function __construct() {
// Run the constructor in the Base class
parent::__construct(10);
}
public function handle(){
echo $this->var;
}
}
(new ChildC())->handle();