2011-02-15 128 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(顯然,這取決於變量範圍)相同。