I'm sorry this appears to be a beginners question. How do I access a parent-class object variables in its extended classes?
class FOO {
public $foo;
function __construct() {
$this->foo = 'string';
}
}
class Parent {
public $x;
function __construct() {
$this->x = new FOO();
var_dump($x); // this works
}
}
class Child extends Parent {
public $y;
function __construct() {
var_dump($this->x); // appears to be NULL all the time
}
}
how do I pass the value or reference of $x correctly?
Your Child
class has its own x
property. Children inherit everything that isn't private, so all public
and protected
properties/methods will be available.
You declare the property x
, but it's not initialized until the Parent
constructor is called. If a child class (in this case Child
) has its own constructor, the parent constructor is overridden and will not be called automatically
In short: You have to call a parent's constructor explicitly from within the child class:
class Child extends Parent
{
protected $y = 'Some string';//you can initialize properties here, too
//ALWAYS use access modifiers
public function __construct()
{
parent::__construct();//explicit call to parent constructor
var_dump($this->x);
}
}
Mind you: if the parent constructor expects an argument, then the child must do the same (signatures must match). The argument types should be compatible (if not: there's a breach of contract), and you'll probably want to pass the arguments to the parent constructor, for it to do its job, too.
Having constructors create new instances that the class needs internally is considered to be bad practice, BTW. Google : S.O.L.I.D., pay special attention to Dependency Injection and the Liskov Principle, and Type hinting.
If you read through the material, you'll understand why this is the better way to write your code:
class Dad
{
/**
* @var Foo
*/
protected $x = null;
public function __construct(Foo $foo)
{
$this->x = $foo;
}
}
//child
class Son extends Dad
{
/**
* @var string
*/
protected $y = 'Some string';
public function __construct(Foo $foo)
{
parent::__construct($foo);
}
public function test()
{
$results = array();
$results[] = '$this->x instanceof Foo ? '.($this->x instanceof Foo ? 'Of course!': 'No');
$results[] '$this instanceof Son ? '.($this instanceof Son ? 'Yup' : 'No?');
$results[] '$this instanceof Dad ? '.($this instanceof Dad ? 'Yes!' : 'No?');
return $results;//methods don't echo, they return...
}
}
$son = new Son(new Foo());
echo implode(PHP_EOL, $son->test());
The output of this code will be
$this->x instanceof Foo ? Of Course!
$this instanceof Son ? Yup
$this instanceof Dad ? Yes!
This seems to confuse many people who are (relatively) new to OOP, but a child class is of the same type as its parent. If you think about it, it makes sense. To the outside world (ie the code that works on/with an instance of a given class), only the public methods are visible. By definition, a child inherits everything that is public, so to the outside world, it doesn't really matter.
if some piece of code requires a Dad
instance to do something, then a Son
will work, too, because all that a Dad
offers, a Son
can do, too. The only thing a child class does is add to the functionality that a parent class already provides.
You need to call Parent's constructor in Child's constructor, it's not called automatically :
class Child extends Parent {
public $y;
function __construct() {
parent::__construct();
var_dump($this->x); // appears to be NULL all the time
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With