可能重复:
New self vs. new static
以下示例中使用self
和static
有什么区别?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
1234
1234
答案 0 :(得分:165)
当您使用self
引用类成员时,您指的是使用该关键字的类。在这种情况下,您的Foo
类定义了一个名为$bar
的受保护静态属性。当您在self
类中使用Foo
来引用该属性时,您将引用同一个类。
因此,如果您尝试在self::$bar
课程的其他位置使用Foo
但是您的Bar
课程的属性值不同,则会使用Foo::$bar
代替Bar::$bar
,可能不是你想要的:
class Foo
{
protected static $bar = 1234;
}
class Bar extends Foo
{
protected static $bar = 4321;
}
当您使用static
时,您正在调用名为late static bindings的功能(在PHP 5.3中引入)。
在上面的方案中,使用static
代替self
会导致使用Bar::$bar
而不是Foo::$bar
,因为解释程序会考虑重新声明Bar
上课。
您通常对方法使用后期静态绑定,甚至使用类本身而不是属性,因为您不经常在子类中重新声明属性;可以在此相关问题中找到使用static
关键字调用后期绑定构造函数的示例:New self vs. new static
但是,这并不排除在static
中使用属性。
答案 1 :(得分:43)
self - refers to the same class whose method the new operation takes place in.
static - in PHP 5.3's late static binding refers to whatever class in the hierarchy which you call the method on.
在下面的示例中(参见get_called_class()),B类继承了A类中的两个方法.Self绑定到A,因为它在A的方法实现中定义,而static绑定到被调用的类,尽管事实上它也在A的方法实现中。
class A {
public static function get_A() {
return new self();
}
public static function get_me() {
return new static();
}
}
class B extends A {}
echo get_class(B::get_A()); // A
echo get_class(B::get_me()); // B
echo get_class(A::get_me()); // A
答案 2 :(得分:2)
我有一个小示例显示self
和static
之间的区别。使用static::
执行后期静态绑定,从而绑定子类中的变量值。
class A { // Base Class
protected static $name = 'ClassA';
public static function getSelfName() {
return self::$name;
}
public static function getStaticName() {
return static::$name;
}
}
class B extends A {
protected static $name = 'ClassB';
}
echo B::getSelfName(); // ClassA
echo B::getStaticName(); // ClassB
答案 3 :(得分:1)
如上所述,主要区别之一是static
允许后期静态绑定。我发现的最有用的方案之一是为Singleton类创建基类:
class A { // Base Class
protected static $name = '';
protected static function getName() {
return static::$name;
}
}
class B extends A {
protected static $name = 'MyCustomNameB';
}
class C extends A {
protected static $name = 'MyCustomNameC';
}
echo B::getName(); // MyCustomNameB
echo C::getName(); // MyCustomNameC
在基类中使用return static::$name
将返回扩展时静态附加的内容。如果要使用return self::$name
,则B::getName()
将返回一个空字符串,因为这是在基类中声明的。
答案 4 :(得分:1)
通过self
通话:
class Foo
{
protected static $var = 123;
public function getVar()
{
return self::$var;
}
}
class Bar extends Foo
{
protected static $var = 234;
}
// Displays: "123"
echo (new Bar)->getVar();
您可以在上面看到,即使我们用$var
类覆盖了Bar
,它仍然返回123
,因为我们已经明确要求PHP提供self
变量,该变量反过来要求Foo
的变量。
现在,如果我们将呼叫与static
交换,我们将获得Bar
的替代值:
通过static
通话:
class Foo
{
protected static $var = 123;
public function getVar()
{
return static::$var;
}
}
class Bar extends Foo
{
protected static $var = 234;
}
// Displays: "234"
echo (new Bar)->getVar();
答案 5 :(得分:1)
也许这段自我解释的代码可以帮助您:
class Foo { protected static $bar = 'parent value'; public static function test() { var_dump('I am your father'); var_dump('self:: here means '.self::$bar); var_dump('static:: here means '.static::$bar); } } class Bar extends Foo { protected static $bar = 'child value'; public static function test() { parent::Test(); var_dump('I am the child'); var_dump('self:: here means '.self::$bar); var_dump('static:: here means '.static::$bar); } } Bar::test(); Foo::test();
这将产生以下输出(为清楚起见,我添加了换行符):
'I am your father' (length=16)
'self:: here means parent value' (length=30)
'static:: here means child value' (length=31)
'I am the child' (length=14)
'self:: here means child value' (length=29)
'static:: here means child value' (length=31)
'I am your father' (length=16)
'self:: here means parent value' (length=30)
'static:: here means parent value' (length=32)