从父类访问子变量?

5

我该怎么做?

class test
{
    public static function run() {
        echo "Number is: ".$num;
    }
} 

class testchild extends test
{
    protected static $num = 5;
    public static function exec()  {
        $num = 5;
        parent::run();
    }
}

testchild::exec();报错显示"num"未定义变量。

http://ideone.com/WM7tHk

如何访问该变量?


1
我恭敬地建议阅读 PHP 面向对象编程文档(至少),因为您似乎没有正确处理面向对象编程的基础知识:http://www.php.net/manual/zh/language.oop5.php - gontrollez
3个回答

6

你不应该这样做,因为你要求父元素去访问可能存在也可能不存在的内容。

最简单的方法是在父元素中声明$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();
    }
    // We always return 42. Or maybe the Unix timestamp, who knows.
    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);

    // A concrete function to initialize the known object would be nice here.
}

class testchild extends test
{
    protected static $info; // This is an array, out of laziness.
                            // It ought to be converted to an object.

    public static function exec()  {
        static::$info['num'] = 5;   // Typo here == possibly subtle bug.
        parent::run();
    }
    protected static function tell($what) {
        return static::$info[$what];  // array_key_exists would be nice here.
    }
}

小改进

为了确保通信时每个对象在同一平台上,您可以使用一个 setter 来抽象通信对象(现在它也可以是数组):

    public static function exec()  {
        static::say('num', 5);
        parent::run();
    }
    protected static function say($what, $value) {
        // array_key_exists would be nice here too.
        static::$info[$what] = $value;
    }

然后初始化将把对象的键设置为默认值,尝试设置不存在的键可能会引发异常。当然,您需要仔细计划在不同的子类中需要设置哪些信息以及如何设置;这并不是一个好的实践,因为更改现在往往会从子级向父级和兄弟级传播。


1
我对第二个例子印象深刻,伙计。它将真正帮助很多人。需要更多的投票支持! - Shankar Narayana Damodaran
谢谢,但要记住这部分是“不太稳定的”。设计测试以确保您不会自食其果。我的手脚现在看起来像筛子,我知道我在说什么 :-) - LSerni

4
class test
{
    public static function run() {
        $c = get_called_class(); //get child class variable in parent class
        echo "Number is: ".$c::$num;
    }
}

class testchild extends test
{
    protected static $num = 5;
    public static function exec()  {
        $num = 5;
        parent::run();
    }
}
testchild::exec();

输出: 数字是:5

在父类的静态方法中使用 get_called_class() 函数获取子类变量。

更多信息:http://php.net/manual/zh/function.get-called-class.php


0

你的父类应该包含它想要访问的变量,例如:

class test
{
    protected static $num;
    public static function run()
    {
        echo "Number is: ".self::$num;
    }
}

class testchild extends test
{
    public static function exec()
    {
        self::$num = 5;
        parent::run();
    }
}

testchild::exec();

Here, the protected qualifier is required. This denotes that the variable can only be accessed by the current class and its descendants. Private, on the other hand, cannot be accessed by descendants.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接