是否从父类访问子类静态变量



我有一个基类,需要调用子类中引用的类上的函数。

很简单,

class base_class {
public function doSomethingWithReference(){
$this->reference->doSomething();
}
}
class extended_class extends base_class{
protected $reference;
public function __construct($ref){
$this->reference = $ref;
}
}

现在这显然很好,

但是,当我调试时,我不关心$this->reference的值

但是,$this->reference所指的对象是巨大的!

所以,当我做print_r($instanceOfExtendedClass)时,我得到了该对象的打印结果。

现在,对于扩展base_class的每个类,引用都是不同的。

我想做的只是将reference设置为extended_class类的静态属性。

但是,将doSomethingWithReference更改为self::$reference会引发未定义的变量错误。

相反,在base_class中设置静态变量并从extended_class中修改它是不起作用的,因为它会更改从该类扩展的所有变量。

有什么办法可以做到这一点,这样我就不会从$this->reference上打印出来吗?

因为您使用的是PHP 5.3,所以可以在运行时使用后期静态绑定来解析对正确类的静态调用。

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

大脂肪提醒:一个extended_class::$reference将在所有extended_class实例之间共享。如果这不是你想要的,这是行不通的。

你似乎真的很担心内存或资源的使用。在PHP中,所有对象都是通过引用传递的。这意味着将对象作为参数传递或创建其副本等不会消耗额外的内存。如果您需要在许多其他对象中引用一个对象,这样做将而不是消耗额外的内存。


如果我有extended_class和另一个相同的类(比如extended_cclass1),它们也会共享引用吗?或者所有extended_class实例共享一个引用,而所有extended.class1实例共享另一个引用(理想情况)?

看起来共享是基于静态变量的定义位置。两个例子,都来自PHP交互式提示:

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

在这种情况下,因为引用位于基类中,所以每个人都看到相同的引用。我想这是有道理的。

当我们用每个子类声明引用时会发生什么。。大部分时间?

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

因为3从1继承而来,没有声明它自己的静态属性,所以它继承了1的。当我们将3设置为Shared(3)时,它会覆盖1的现有Shared(1)。

结论:为了实现这一点,需要在每个需要唯一引用的类中声明属性。请注意,此代码自5.4.x.起有效

为父级提供访问子级静态成员的方法:

<?php
abstract class base_class {
abstract protected function reference();
// If you want to be able to instanciate base class directly, use the following 2 lines in place of the previous 2 lines:
//class base_class {
//protected function reference() {}
public function doSomethingWithReference(){
$this->reference()->doSomething();
}
}
class extended_class extends base_class{
protected static $reference;
public function __construct($ref){
self::$reference = $ref;
}
protected function reference(){
return self::$reference;
}
}
class ref {
public function doSomething(){
echo __METHOD__;
}
}
$ref = new ref();
$ec = new extended_class($ref);
$ec->doSomethingWithReference();
print_r($ec);
?>

最新更新