[英]Access parent and child variables in method defined in parent - PHP
我有一個從父對象繼承的子對象。 兩者都有一個靜態變量,它在每個對象中都有不同的值; 當我實例化子項時,我想將該變量從父項和子項添加到數組中。 為了節省重復的代碼,我在父類中編寫了一個方法( addFoo
),該方法從父類和子類構造函數中調用。 但是,我似乎無法找到一種方法來區分從子構造函數調用父構造函數時的調用(如下所示,無論使用$this
self
,方法的輸出在兩種情況下都是相同的)或static
)。
class A {
public static $foo = 'foo';
public $thisvars = array();
public $selfvars = array();
public $staticvars = array();
public function __construct() {
$this->addFoo();
}
public function addFoo() {
$this->selfvars[] = self::$foo;
$this->staticvars[] = static::$foo;
$this->thisvars[] = $this::$foo;
}
}
class B extends A {
public static $foo = 'bar';
public function __construct() {
parent::__construct();
$this->addFoo();
}
}
$b = new B;
print_r($b->selfvars);
print_r($b->staticvars);
print_r($b->thisvars);
輸出:
Array
(
[0] => foo
[1] => foo
)
Array
(
[0] => bar
[1] => bar
)
Array
(
[0] => bar
[1] => bar
)
我可以通過將調用類傳遞給addFoo
函數(見下文)來解決這個問題,但是有沒有更好的(正確的?)方法嗎?
class C {
public static $foo = 'foo';
public $vars = array();
public function __construct() {
$this->addFoo(__CLASS__);
}
public function addFoo($class) {
$this->vars[] = $class::$foo;
}
}
class D extends C {
public static $foo = 'bar';
public function __construct() {
parent::__construct();
$this->addFoo(__CLASS__);
}
}
$d = new D;
print_r($d->vars);
輸出:
Array
(
[0] => foo
[1] => bar
)
不是讓每個子構造函數都調用addFoo
,一種方法是在基構造函數調用的基類中使用單個addFoos
方法,該方法將從后期靜態綁定類開始附加所有$foo
值:
class A
{
public static $foo = 'foo';
public $vars = [];
public function __construct()
{
$this->addFoos();
}
private function addFoos()
{
$class = static::class;
do {
$this->vars[] = $class::$foo;
} while ($class = get_parent_class($class));
}
}
class B extends A
{
public static $foo = 'bar';
}
class C extends B
{
public static $foo = 'baz';
}
$a = new A;
print_r($a->vars); // ['foo']
$b = new B;
print_r($b->vars); // ['bar', 'foo']
$c = new C;
print_r($c->vars); // ['baz', 'bar', 'foo']
該方法被標記為private
因為在這種情況下它不應該被擴展(也不應該從外部調用)。
我或者會考慮另一種更直接的方法:
class A
{
public static $foo = 'foo';
public function getVars()
{
return [self::$foo];
}
}
class B extends A
{
public static $foo = 'bar';
public function getVars()
{
return array_merge(parent::getVars(), [self::$foo]);
}
}
class C extends B
{
public static $foo = 'baz';
public function getVars()
{
return array_merge(parent::getVars(), [self::$foo]);
}
}
$a = new A;
print_r($a->getVars()); // ['foo']
$b = new B;
print_r($b->getVars()); // ['foo', 'bar']
$c = new C;
print_r($c->getVars()); // ['foo', 'bar', 'baz']
在這種情況下,您確實必須在每個子類上重新定義getVars
,但畢竟,每個類決定應該公開哪些變量是有意義的。 在此過程中,您的代碼變得不那么晦澀/更易於維護。
如果一個類不需要/想要“貢獻”,您可以簡單地省略getVars
的靜態屬性和getVars
擴展。
筆記:
A
的$vars
屬性中,array_merge
,$foo
靜態屬性是否需要是public
,但我已經將它們保留為您的問題中的樣子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.