我不明白为什么在下面的代码中,$ my_foo和$ my_bar被子类正确继承,但如果我通过赋予$ my_var的引用来更改$ my_foo,则子类仍会看到原始价值..
<?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
编辑:这是一个类似的问题:do extended classes inherit static var values (PHP)?但我的更专注于继承和引用。
EDIT2:请注意,这个问题的重点不在于后期静态绑定,但这就是为什么,因为$ my_foo和$ my_bar是继承的,在Foo中更改它们并不会影响它们在酒吧。而仅在参考时发生。事实上,如果我们改变:
public static function break_inheritance() {
self::$my_bar = self::$my_foo; // removed reference in assignment
}
行为完全改变,最后一个Bar :: bar_print_vars(); // OUTPUTS foo foo
答案 0 :(得分:0)
Foo与Bar不同。尝试拨打Bar::break_inheritance();
,看看会发生什么。
答案 1 :(得分:0)
将类的静态属性视为具有奇特名称的全局变量。
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();
修改Foo::$my_bar
。它不会影响Bar::$my_bar
。
如果你把它称为:
Bar::break_inheritance();
它仍会更改Foo::$my_bar
,但不会影响Bar::$my_bar
。
使用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->
对常规属性和方法的工作方式相同。它使用在您使用它的类中定义的属性或方法(在子类中),如果有的话,而不是从父类继承的属性或方法。
答案 2 :(得分:0)
这是因为PHP 5.3.0版中引入了一个名为Late static binding的新功能。
Late static binding
来自于static ::不会使用定义方法的类来解析,而是使用运行时信息来计算。