继承类中静态属性的层次结构



我想在类中定义一个静态属性,并让每个子类都有自己的属性值。

以下是我尝试过的:

class A {
static protected $v = "A";

static public function getV() {
return static::$v;
}
static public function setV($value) {
static::$v = $value;
}
}
class B extends A {}
class C extends A {}
B::setV("B");
print_r(A::getV());
print_r(B::getV());
print_r(C::getV());
print_r("n");
C::setV("C");
print_r(A::getV());
print_r(B::getV());
print_r(C::getV());
print_r("n");

我所期望的:

ABA // C::$v hasn't been initialized, so it holds the parent's value
ABC

我得到的:

BBB
CCC

因此,只有一个属性可用,而且是父属性的属性。为了得到我期望的结果,我必须重新声明并初始化子类中的静态属性:

class B extends A {
static protected $v;
static public function init() {
self::$v = parent::$v;
}
}
B::init();
class C extends A {
static protected $v;
static public function init() {
self::$v = parent::$v;
}
}
C::init();

结果:

ABA
ABC

有没有一种更优雅的方法可以做到这一点,而不必在子类中重新声明和初始化我的属性?

您可以使用一个数组来代替标量变量,该数组包含每个类的所有初始化值。然而,这不是一个好的解决方案,因为它受到静态变量的限制。

class A {
static protected $v = array("A" => "A");
static public function getV() {
return static::$v[get_called_class()] ?? static::$v[get_class()];
}
static public function setV($value) {
static::$v[get_called_class()] = $value;
}
}

最新更新