【发布时间】:2012-03-21 08:02:14
【问题描述】:
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"
显然,如果 static::$bar 没有在每个孩子(兄弟,姐妹)中明确重新定义,他们的父母(母亲)将为他们设置值(或至少为那些没有重新定义它的人)。
问题:有什么办法可以防止没有重新定义 static::$bar 的孩子接收到新的值?换句话说,如何确保只有被引用的类获得一个新值,即使 static::$bar 没有在每个孩子中显式地重新定义?
【问题讨论】:
-
我只看到一个选项来实现这一点。您必须覆盖姊妹类中的 getBar 和 setBar 方法。 setBar 方法写入 $this->bar,getBar 检查是否设置了 $this->bar,否则从 parent::$bar 检索。
-
当你有一个对象实例时,是否有理由让这些静态?
-
@Dan 你可能是对的。另一种选择是在每个孩子中重新声明 static::$bar。问题是没有办法强制程序员这样做。
-
@DaveC 每个对象都将具有相同的值,因此在每个实例中拥有它的副本似乎很浪费。
-
静态变量(和关联值)的全部目的是跨实例化。