覆盖静态变量
override a static variable
我有两个 classes(模型和用户)但是我有一个问题所以我试图用一个简单的例子来解释它:
class person
{
protected static $todo ="nothing";
public function __construct(){}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
protected static $todo ="studing";
}
$s = new student();
$s->get_what_todo(); // this will show the word (nothing)
//but I want to show the word (studing)
请给我一个解决方案,但不要在学生中写任何函数class我只想在那里做声明:)谢谢:)
你可以尝试在构造中设置变量
class person
{
protected static $todo = null;
public function __construct(){
self::$todo = "nothing";
}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
public function __construct() {
self::$todo = "student";
}
}
$s = new student();
$s->get_what_todo();
该原理称为“late static binding”,在PHP 5.3.0 中引入;使用 self
关键字访问继承树中调用 class 中定义的 属性,或使用 static
访问子 [=] 中定义的 属性 17=] 在该继承树中。
class person
{
protected static $todo ="nothing";
public function __construct(){}
public function get_what_todo()
{
echo static::$todo; // change self:: to static::
}
}
class student extends person
{
protected static $todo ="studying";
}
class teacher extends person
{
protected static $todo ="marking";
}
class guest extends person
{
}
$s = new student();
$s->get_what_todo(); // this will show the "studying" from the instantiated child class
$t = new teacher();
$t->get_what_todo(); // this will show the "marking" from the instantiated child class
$g = new guest();
$g->get_what_todo(); // this will show the "nothing" from the parent class,
// because $todo is not overriden in the child class
你可以尝试在构造中设置父变量
class person
{
protected static $todo = null;
public function __construct(){
self::$todo = "nothing";
}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
public function __construct() {
parent::$todo = "student";
}
}
$s = new student();
$s->get_what_todo();
覆盖静态变量的可靠方法是重新声明它。可能有人建议在construct方法中修改,我觉得不靠谱。
在 class 至少构造一次之前,它不会反映更改。当然,在 class 方法中,当您想始终访问被覆盖的变量时,不要忘记使用“static::”而不是“self::”来调用静态变量。
这是我的意思的一个例子:
class Foo 是基础 class,class Bar 在其构造函数中更改变量,而 class Baz 在其声明中覆盖变量。
class Foo
{
public static $a = "base";
}
class Bar extends Foo
{
function __construct()
{
self::$a = "overridden";
}
}
class Baz extends Foo
{
public static $a = "overridden";
}
echo 'Foo: ' . Foo::$a . '<br>';
echo 'Bar: ' . Bar::$a . '<br>';
echo 'Baz: ' . Baz::$a . '<br>';
new Bar();
echo 'Bar after instantiation: ' . Bar::$a;
的输出
Foo: base
Bar: base
Baz: overridden
Bar after instantiation: overridden
如您所见,Bar 更改变量的方式在至少调用构造函数一次后才会生效。
EDIT: 但是,还有另一种永久可靠地编辑变量的方法:在 class 声明之后进行。如果您只需要修改一个变量而不是完全覆盖它,例如数组,这将特别方便。感觉有点脏,但理论上应该每次都能用。
class Foo
{
public static $a = [
'a' => 'a'
];
}
class Bar extends Foo
{
public static $a;
}
Bar::$a = Foo::$a;
Bar::$a['b'] = 'b';
echo 'Foo: ' . print_r(Foo::$a, true) . '<br>';
echo 'Bar: ' . print_r(Bar::$a, true) . '<br>';
的输出
Foo: Array ( [a] => a )
Bar: Array ( [a] => a [b] => b )
编辑 2:ReflectionClass::getStaticPropertyValue 在我的测试中也采用了最后一种方法。
我有两个 classes(模型和用户)但是我有一个问题所以我试图用一个简单的例子来解释它:
class person
{
protected static $todo ="nothing";
public function __construct(){}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
protected static $todo ="studing";
}
$s = new student();
$s->get_what_todo(); // this will show the word (nothing)
//but I want to show the word (studing)
请给我一个解决方案,但不要在学生中写任何函数class我只想在那里做声明:)谢谢:)
你可以尝试在构造中设置变量
class person
{
protected static $todo = null;
public function __construct(){
self::$todo = "nothing";
}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
public function __construct() {
self::$todo = "student";
}
}
$s = new student();
$s->get_what_todo();
该原理称为“late static binding”,在PHP 5.3.0 中引入;使用 self
关键字访问继承树中调用 class 中定义的 属性,或使用 static
访问子 [=] 中定义的 属性 17=] 在该继承树中。
class person
{
protected static $todo ="nothing";
public function __construct(){}
public function get_what_todo()
{
echo static::$todo; // change self:: to static::
}
}
class student extends person
{
protected static $todo ="studying";
}
class teacher extends person
{
protected static $todo ="marking";
}
class guest extends person
{
}
$s = new student();
$s->get_what_todo(); // this will show the "studying" from the instantiated child class
$t = new teacher();
$t->get_what_todo(); // this will show the "marking" from the instantiated child class
$g = new guest();
$g->get_what_todo(); // this will show the "nothing" from the parent class,
// because $todo is not overriden in the child class
你可以尝试在构造中设置父变量
class person
{
protected static $todo = null;
public function __construct(){
self::$todo = "nothing";
}
public function get_what_todo()
{
echo self::$todo;
}
}
class student extends person
{
public function __construct() {
parent::$todo = "student";
}
}
$s = new student();
$s->get_what_todo();
覆盖静态变量的可靠方法是重新声明它。可能有人建议在construct方法中修改,我觉得不靠谱。
在 class 至少构造一次之前,它不会反映更改。当然,在 class 方法中,当您想始终访问被覆盖的变量时,不要忘记使用“static::”而不是“self::”来调用静态变量。
这是我的意思的一个例子: class Foo 是基础 class,class Bar 在其构造函数中更改变量,而 class Baz 在其声明中覆盖变量。
class Foo
{
public static $a = "base";
}
class Bar extends Foo
{
function __construct()
{
self::$a = "overridden";
}
}
class Baz extends Foo
{
public static $a = "overridden";
}
echo 'Foo: ' . Foo::$a . '<br>';
echo 'Bar: ' . Bar::$a . '<br>';
echo 'Baz: ' . Baz::$a . '<br>';
new Bar();
echo 'Bar after instantiation: ' . Bar::$a;
的输出
Foo: base
Bar: base
Baz: overridden
Bar after instantiation: overridden
如您所见,Bar 更改变量的方式在至少调用构造函数一次后才会生效。
EDIT: 但是,还有另一种永久可靠地编辑变量的方法:在 class 声明之后进行。如果您只需要修改一个变量而不是完全覆盖它,例如数组,这将特别方便。感觉有点脏,但理论上应该每次都能用。
class Foo
{
public static $a = [
'a' => 'a'
];
}
class Bar extends Foo
{
public static $a;
}
Bar::$a = Foo::$a;
Bar::$a['b'] = 'b';
echo 'Foo: ' . print_r(Foo::$a, true) . '<br>';
echo 'Bar: ' . print_r(Bar::$a, true) . '<br>';
的输出
Foo: Array ( [a] => a )
Bar: Array ( [a] => a [b] => b )
编辑 2:ReflectionClass::getStaticPropertyValue 在我的测试中也采用了最后一种方法。