2011-02-15 138 views
2

我想将抽象父类中的属性与子类中的相同属性合并。代码看起来有点像这样(除了在我的实现,在有关财产是一个数组,而不是一个整数):合并父类和子类的属性

abstract class A { 
    public $foo = 1; 

    function __construct() { 
     echo parent::$foo + $this->foo; # parent::$foo NOT correct 
    } 
} 

class B extends A { 
    public $foo = 2; 
} 

$obj = new B(); # Ideally should output 3 

现在我认识到作为意在构造父:: $ foo的将无法正常工作在这里,但是如何合并属性值而不将值硬编码到构造函数中或在父类中创建附加属性?

+0

好吧我想我找到了一个使用反射的解决方案。在A的构造函数中,我可以这样做:`$ r = new ReflectionClass();提取($ r-> getDefaultProperties());` – 2011-02-15 23:55:32

回答

2

你不能直接做到这一点。你需要在B构造函数来定义它,因为B->$foo将在编译时覆盖A的(因此A->$foo将丢失):

abstract class A { 
    public $foo = 1; 
    function __construct() { 
     echo $this->foo; 
    } 
} 

class B extends A { 
    public function __construct() { 
     $this->foo += 2; 
    } 
} 

现在,有周围的办法,但它们涉及Reflection变脏。不要这样做。只需在构造函数中增加它,然后完成...

+0

我实际上想要做的是array_merge,而不是简单的算术。另外,我不想覆盖抽象的构造函数......它有点失败了。 – 2011-02-15 23:22:23

0

你不能。你有最好的选择是有另一个属性。我知道你已经知道这一点,但这是最好的解决方案。

<?php 
class A { 
    protected $_foo = 2; 
} 

class B extends A { 
    protected $foo = 3; 
    function bar() { 
     return $this->_foo + $this->foo; 
    } 
} 

这是你最好的选择。

2

在父类的构造函数,做这样的事情:

<?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) 

基本上,魔法来自get_class_vars()功能,这将返回在特定的类中设置的属性,无论价值设置在儿童班。

如果你想获得与该函数的父类值,你可以做任何的从父类本身如下:get_class_vars(__CLASS__)get_class_vars(get_class())

如果你想获得ChildClass值,你可以做以下来自ParentClass或ChildClass:get_class_vars(get_class($this)),尽管这与访问$this->var_name(显然,这取决于变量范围)相同。