PHP:将静态变量范围限制为特定类

时间:2012-03-02 20:10:46

标签: php oop static instance

abstract class Mother {
        protected static $foo = null;
        protected static $bar = null;

        public function getFoo() { return static::$foo; }
        public function getBar() { return static::$bar; }
        public function setFoo($foo) { static::$foo = $foo; }
        public function setBar($bar) { static::$bar = $bar; }
}

class Brother extends Mother {
        protected static $foo = 'BROTHERS';
}

class Sister extends Mother {
        protected static $foo = 'SISTERS';
}

$brother1 = new Brother();
$brother2 = new Brother();
$sister1 = new Sister();
$sister2 = new Sister();

$sister1->setBar('ONLY SISTERS'); // We set $bar = 'ONLY SISTERS' at sister1.
// We want only Sister instances to get this value...
// however Brother instances also get this value!

    echo '<p>Brother 1: Foo="'.$brother1->getFoo().'", Bar="'.$brother1->getBar().'"</p>';
// Foo="BROTHERS", Bar="ONLY SISTERS"
    echo '<p>Brother 2: Foo="'.$brother2->getFoo().'", Bar="'.$brother2->getBar().'"</p>';
// Foo="BROTHERS", Bar="ONLY SISTERS"
    echo '<p>Sister 1: Foo="'.$sister1->getFoo().'", Bar="'.$sister1->getBar().'"</p>';
// Foo="SISTERS", Bar="ONLY SISTERS"
    echo '<p>Sister 2: Foo="'.$sister2->getFoo().'", Bar="'.$sister2->getBar().'"</p>';
// Foo="SISTERS", Bar="ONLY SISTERS"

显然,如果静态:: $ bar未在每个孩子(兄弟,姐妹)中明确重新定义,他们的父母(母亲)将为他们设定值(或至少为那些没有重新定义它的人)。

问题:有没有办法阻止没有重新定义static :: $ bar的孩子接收新值?换句话说,如何确保只有被引用的类获得一个新值,即使在每个子节点中没有显式重新定义static :: $ bar,也是如此?

2 个答案:

答案 0 :(得分:2)

不,不是你这样做的方式。这就是私人范围。子类继承所有公共和受保护的静态属性 - 这意味着它们都指向相同的值,无论它们是父级,子级还是兄弟级。

这是正确和良好的OO。

您应该在父类中将变量定义为私有静态,然后子项将无法直接看到它,并且可以根据需要创建自己的私有静态变量。

在类中提供静态getter和setter以访问私有静态属性。

Brother::getFoo();
Sister::getFoo();

你可以在父类中创建getFoo()母抽象与否,如果你需要直接访问它,那么你可以这样做:

Mother::getFoo();

答案 1 :(得分:1)

这只是疯狂。

您应该了解extend定义 IS A 关系。例如:class Duck extends Bird{}这意味着Duck的每个实例都是Bird

因此,在您的示例中,每个Brother都是Mother。我没有看到这有多大意义。


另一件事:你为什么滥用静态变量?你在做什么不是面向对象的编程。您只是将全局范围变量和函数包装在命名空间中(恰好看起来像类)。

有关该主题的一些其他链接,您可能会觉得有用: