When dealing with inheritance in PHP I found some lack of knowledge, mainly about constructors and private properties.
Let's take this code as example:
<?php
class Module
{
public $type;
public function __construct($type)
{
$this->type = $type;
}
}
class BModule extends Module
{
}
class CModule extends BModule
{
}
class A
{
private $module;
public function __construct(Module $module)
{
echo 'Set module for '.__CLASS__.' to '.$module->type . PHP_EOL;
echo "<br>";
$this->module = $module;
}
public function getModule()
{
echo "I (as " . __CLASS__ . ") have a module of type " . $this->module->type;
return $this->module->type;
}
}
class B extends A
{
}
$m = new Module('base-module');
$bm = new BModule('bi-module');
echo "<br>--------A---------<br>";
$a = new A($m);
echo "<br>A is of type " . $a->getModule();
echo "<br>--------B---------<br>";
$b = new B($bm);
echo "<br>B is of type " . $b->getModule();
Some questions:
- shouldn't B construction call the constructor in the context of B? (and so I would expect it to fail cause it didn't inherited the private property $module)
- or PHP would simply call the A constructor, using/referencing methods and properties from A? (including the private ones)
- I can pass to $b either a Module or a BModule object; this is because BModule is a child of Module. Is PHP checking some inheritance chain (checking the parents) of the passed object when verifying the type hinting?
- so can I pass to the constructor either an object of type Module or BModule or CModule?
And this is another example:
<?php
class a
{
private $a;
protected $a_copy;
public function __construct($a_value)
{
$this->a = $a_value;
$this->a_copy = $this->a;
}
public function getA()
{
return $this->a;
}
public function getCopyA()
{
return $this->a;
}
}
class b extends a
{
}
$a = new a('value for a');
$b = new b('value for b');
echo "<br>-----A-----<br>";
echo $a->getA()."<br>";
echo $a->getCopyA()."<br>";
echo "<br>-----B-----<br>";
echo $b->getA()." (I would expect to have no access to \$a)<br>";
echo $b->getCopyA()."<br>";
Being the property $a private, I would expect to not be able to access it or do anything with it from the class b. It is a little bit non-sense for my actual understanding.