Merging properties of parent and child classes
I am trying to merge a property in an abstract parent class with the same property in a child class. The code looks sort of like this (except in my implementation, the property in question is an array, not an integer):
abstract class A {
public $foo = 1;
function __construct() {
echo parent::$foo + $this->foo; # parent::$foo 开发者_JS百科NOT correct
}
}
class B extends A {
public $foo = 2;
}
$obj = new B(); # Ideally should output 3
Now I realize that parent::$foo in the constructor will not work as intended here, but how does one go about merging the property values without hardcoding the value into the constructor or creating an additional property in the parent class?
In the constructor of your parent class, do something like this:
<?php
abstract class ParentClass {
protected $foo = array(
'bar' => 'Parent Value',
'baz' => 'Some Other Value',
);
public function __construct( ) {
$parent_vars = get_class_vars(__CLASS__);
$this->foo = array_merge($parent_vars['foo'], $this->foo);
}
public function put_foo( ) {
print_r($this->foo);
}
}
class ChildClass extends ParentClass {
protected $foo = array(
'bar' => 'Child Value',
);
}
$Instance = new ChildClass( );
$Instance->put_foo( );
// echos Array ( [bar] => Child Value [baz] => Some Other Value )
Basically, the magic comes from the get_class_vars( )
function, which will return the properties that were set in that particular class, regardless of values set in child classes.
If you want to get the ParentClass values with that function, you can do either of the following from within the ParentClass itself: get_class_vars(__CLASS__)
or get_class_vars(get_class( ))
If you want to get the ChildClass values, you can do the following from within either the ParentClass, or the ChildClass: get_class_vars(get_class($this))
although this is the same as just accessing $this->var_name
(obviously, this depends on variable scope).
You can't directly do that. You'd need to define it in the constructor of B
, since B->$foo
would overwrite A
's at compile time (and hence A->$foo
would be lost):
abstract class A {
public $foo = 1;
function __construct() {
echo $this->foo;
}
}
class B extends A {
public function __construct() {
$this->foo += 2;
}
}
Now, there are ways around that, but they involve Reflection
and will be dirty. Don't do that. Just increment it in the constructor and be done...
You can't. The best option you have is to have another property. I know that you already know this, but that's the best solution.
<?php
class A {
protected $_foo = 2;
}
class B extends A {
protected $foo = 3;
function bar( ) {
return $this->_foo + $this->foo;
}
}
That's your best bet.
精彩评论