我不明白为什么在下面的代码中,$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
Bar::break_inheritance();
,看看会发生什么。
将类的静态属性视为具有奇特名称的全局变量。
class Foo
{
public static $my_foo = 'foo';
public static $my_bar = 'bar';
// ...
}
上面的代码声明了类Foo
的两个静态属性,它们的全名是Foo::$my_foo
和Foo::$my_bar
。
通过扩展Foo
,类Bar
又产生了两个名为Bar::$my_foo
和Bar::$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::不会使用定义方法的类来解析,而是使用运行时信息来计算。