为什么给静态类变量赋值引用会破坏该变量的继承



我不明白为什么在下面的代码中,$my_foo和$my_bar被子类正确继承,但如果我通过给$my_var分配引用来更改$my_fo0,子类仍然会看到原始值。。

<?php
class Foo
{
public static $my_foo = 'foo';
public static $my_bar = 'bar';
public static function break_inheritance() {
self::$my_bar = &self::$my_foo;
}
public static function foo_print_vars() {
print self::$my_foo." ";
print self::$my_bar."n";
}
}
class Bar extends Foo
{
public static function bar_print_vars() {
print self::$my_foo." ";
print self::$my_bar."n";
}
}

Bar::bar_print_vars(); // OUTPUTS foo bar
Foo::break_inheritance(); 
Foo::foo_print_vars(); // OUTPUTS foo foo
Bar::bar_print_vars(); // OUTPUTS foo bar

编辑:这是一个类似的问题:扩展类继承静态var值(PHP)吗?但我的更侧重于继承和引用。

编辑2:请注意,这个问题的重点不是关于后期静态绑定,而是因为$my_foo和$my_bar是继承的,所以在foo中更改它们不会影响在bar中访问它们。而这种只发生在引用中。事实上,如果我们改变:

public static function break_inheritance() {
self::$my_bar = self::$my_foo; // removed reference in assignment
}

行为完全改变,最后一个Bar::Bar_print_vars();//输出foo foo

Foo与Bar是不同的类。尝试调用Bar::break_inheritance();,看看会发生什么。

将类的静态属性视为具有奇特名称的全局变量。

class Foo
{
public static $my_foo = 'foo';
public static $my_bar = 'bar';
// ...
}

上面的代码声明了类Foo的两个静态属性,它们的全名是Foo::$my_fooFoo::$my_bar

通过扩展Foo,类Bar又产生了两个名为Bar::$my_fooBar::$my_bar的静态属性。

代码:

class Foo
{
public static function break_inheritance() {
self::$my_bar = &self::$my_foo;
}
}
Foo::break_inheritance(); 

修改CCD_ 9。不影响Bar::$my_bar

如果你称之为:

Bar::break_inheritance(); 

它仍然改变CCD_ 11并且不影响CCD_。

使用self::的引用在编译时绑定到使用它的类的属性。这和你写Foo::$my_bar = &Foo::$my_foo;是一样的。无论您如何调用方法break_inheritance(),它都将始终修改Foo::$my_bar

如果要使用方法break_inheritance()更改Bar::$my_bar,则必须将其更改为使用static::而不是self:::

class Foo
{
public static function break_inheritance() {
static::$my_bar = &static::$my_foo;
}
}
Foo::break_inheritance();         // Changes `Foo::$my_bar`
Bar::break_inheritance();         // Changes `Bar::$my_bar`

这被称为late static binding,是在PHP 5.3中引入的。

后期静态绑定(static::)适用于类属性和方法,就像$this->适用于常规属性和方法一样。它使用在您使用它的类(在子类中)中定义的属性或方法(如果有的话),而不是从父类继承的属性或方式。

这是由于PHP 5.3.0版本中引入了名为Late静态绑定的新功能。

Late static binding来源于这样一个事实:static::不会使用定义方法的类来解析,而是使用运行时信息来计算。

最新更新