首页 > 解决方案 > 继承类中静态属性的层次结构

问题描述

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

这是我尝试过的:

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

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

标签: phpinheritance

解决方案


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

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;
    }

}

推荐阅读