Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access child class static variables from parent class?

I have a base class that I need to call functions on a class that is referenced in the child class.

Easy enough,

class base_class {

    public function doSomethingWithReference(){
        $this->reference->doSomething();
    }
}

class extended_class extends base_class{

    protected $reference;

    public function __construct($ref){
        $this->reference = $ref;
    }
}

Now this works fine obviously,

But, when I am debugging I don't care about the value of $this->reference

But, the object that $this->reference refers to is huge!

so, when I do print_r($instanceOfExtendedClass) I get the print out of that object.

Now the reference is different for each class that extends base_class.

What I wanted to do was just set reference as a static property on the extended_class class.

But, then changing doSomethingWithReference to be self::$reference throws an undefined variable error.

And conversely setting the static variable in base_class and modifying it from extended_class doesn't work as it changes the variable for all everything that extends from that class.

Is there any way to do this so I don't get the print out of $this->reference?

like image 722
Hailwood Avatar asked Dec 08 '12 04:12

Hailwood


People also ask

Can a parent class access child class variable?

The reference holding the child class object reference will not be able to access the members (functions or variables) of the child class. This is because the parent reference variable can only access fields that are in the parent class.

Can static variables be accessed from the child class?

You could access static variables of the base class in any of the classes in the same package (default package in your case since no packages are defined). This includes any of the derived classes within the package. If you want to make it available across packages, use the "public" modifier.

Can we have same static method in parent and child class?

We can declare static methods with the same signature in the subclass, but it is not considered overriding as there won't be any run-time polymorphism. Hence the answer is 'No'.

Can we use static method in child class?

If we call a static method by using the parent class object, the original static method will be called from the parent class. If we call a static method by using the child class object, the static method of the child class will be called.


1 Answers

Because you are using PHP 5.3, you can use late static binding to resolve the static call to the right class at runtime.

class base_class {

    public function doSomethingWithReference(){
        static::$reference->doSomething();
    }

}

class extended_class extends base_class{

    protected static $reference;

    public function __construct($ref){
        static::$reference = $ref;
    }

}

Big fat reminder: That one extended_class::$reference is going to be shared amongst all of the extended_class instances. If that is not what you intend, this is not going to work.

You seem to actually be worried about memory or resource use. In PHP, all objects are passed by reference. This means that passing an object as an argument, or creating a copy of it, etc, does not consume extra memory. If you need to reference an object in a number of other objects, doing so will not consume extra memory.


If I had extended_class and another identical class (say extended_class1) would they share the reference as well? or would all extended_class' instances share one reference, while all extended_class1' instances would share another (the ideal case)?

It looks like the sharing is based on where the static variable is defined. Two examples, both from the PHP interactive prompt:

php > class Shared { public $me; public function __construct($me) { $this->me = $me; } }
php > class Base { protected static $ref; public function foo() { echo static::$ref->me, "\n"; } }
php > class Inherit_1 extends Base { public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_2 extends Base { public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_3 extends Inherit_1 {}
php > $shared_1 = new Shared(1)
php > ;
php > $shared_2 = new Shared(2);
php > $shared_3 = new Shared(3);
php >
php > $in_1 = new Inherit_1($shared_1);
php > $in_2 = new Inherit_2($shared_2);
php > $in_3 = new Inherit_3($shared_3);
php >
php > $in_1->foo();
3
php > $in_2->foo();
3
php > $in_3->foo();
3

In this case, because the reference lives in the base class, everyone sees the same one. I suppose this makes some sort of sense.

What happens when we declare the reference with each child class.. most of the time?

php > class Shared { public $me; public function __construct($me) { $this->me = $me; } }
php > class Base { public function foo() { echo static::$ref->me, "\n"; } }
php > class Inherit_1 extends Base { protected static $ref; public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_2 extends Base { protected static $ref; public function __construct($ref) { static::$ref = $ref; } }
php > class Inherit_3 extends Inherit_1 {}
php > class Inherit_4 extends Inherit_1 { protected static $ref; }
php > $shared_1 = new Shared(1);
php > $shared_2 = new Shared(2);
php > $shared_3 = new Shared(3);
php > $shared_4 = new Shared(4);
php > $in_1 = new Inherit_1($shared_1);
php > $in_2 = new Inherit_2($shared_2);
php > $in_3 = new Inherit_3($shared_3);
php > $in_4 = new Inherit_4($shared_4);
php > $in_1->foo();
3
php > $in_2->foo();
2
php > $in_3->foo();
3
php > $in_4->foo();
4

Because 3 inherited from 1 without declaring it's own static property, it inherited 1's. When we set 3's to Shared(3), it overwrote 1's existing Shared(1).

Conclusion: For this to work, the property needs to be declared in every class that needs the single unique reference. Note that this code is valid as of 5.4.x.

like image 198
Charles Avatar answered Oct 09 '22 13:10

Charles