简体   繁体   中英

Accessing child variables from parent class?

How do I do this?

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(); says Undefined variable "num".

http://ideone.com/WM7tHk

How do I access this variable?

You shouldn't be able to do this, because you're requesting the parent to access something that it might be or not be there.

The simplest way would be to declare $num inside the parent . Otherwise you need to take measures to guarantee the system that the information will be there, by supplying (eg) a protected abstract static 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();

Passing several variables

Another, less solid approach would be to have a "communication object" and pass a reference to it. This can be done the same way as above, using a property array or ( better ) an object of known structure:

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

Small improvement

To ensure that every object is on the same board when communicating, you can abstract the communication object (now it could also be an array) with a 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;
    }

Then the initialization would set the object's keys to default values, and trying to set nonexisting keys could raise an exception. Of course you need to carefully plan what information needs to be set in the different child classes, and how; which isn't really a good practice, as changes would now tend to cascade from a child to the parent and thence to the siblings.

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();

Output: Number is: 5

You have got the child class variable using get_called_class () function in a parent class static method.

More information : http://php.net/manual/en/function.get-called-class.php

Your parent class should instead contain the variables which it wishes to access, so, for example:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM