你不应该这样做,因为你要求父元素去访问可能存在也可能不存在的内容。
最简单的方法是在父元素中声明$num
。否则,你需要采取措施来保证系统将会有这个信息,例如提供一个受保护的抽象静态getter。
abstract class test
{
public static function run() {
echo "Number is: ".static::getNum();
}
protected abstract static function getNum();
}
class testchild extends test
{
protected static $num;
public static function exec() {
static::$num = 5;
parent::run();
}
protected static function getNum() {
return static::$num;
}
}
class anotherchild extends test
{
public static function exec() {
parent::run();
}
protected static function getNum() {
return 42;
}
}
$c = new testchild();
$c->exec();
传递多个变量
另一种不太稳定的方法是使用“通信对象”并传递对其的引用。这可以通过使用属性数组或者(更好的)已知结构的对象来完成,与上面的方式相同:
abstract class test
{
public static function run() {
echo "Number is: ".static::tell('num');
}
protected abstract static function tell($what);
}
class testchild extends test
{
protected static $info;
public static function exec() {
static::$info['num'] = 5;
parent::run();
}
protected static function tell($what) {
return static::$info[$what];
}
}
小改进
为了确保通信时每个对象在同一平台上,您可以使用一个 setter 来抽象通信对象(现在它也可以是数组):
public static function exec() {
static::say('num', 5);
parent::run();
}
protected static function say($what, $value) {
static::$info[$what] = $value;
}
然后初始化将把对象的键设置为默认值,尝试设置不存在的键可能会引发异常。当然,您需要仔细计划在不同的子类中需要设置哪些信息以及如何设置;这并不是一个好的实践,因为更改现在往往会从子级向父级和兄弟级传播。