static::中的static其实是运行时所在类的别名,并不是定义类时所在的那个类名。这个东西可以实现在父类中,能够调用子类的方法和属性。
使用(static)关键字来表示这个别名,和静态方法,静态类没有半毛钱的关系,static::不仅支持静态类,还支持对象(动态类)。
所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。
那么非转发调用其实就是明确指定类名的静态调用(foo::bar())和非静态调用($foo->bar())
后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期静态绑定从这里开始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
输出:
B
分析:运行B::test()会调用B中继承自A的test方法,然后会执行static::who(),而static::中的static表示运行时所在类的别名,此时运行的类名是B,所以static::who()就是执行B中的who方法,所以输出B。
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
输出:
A
C
C
分析:运行C::test()会调用C继承自B的test方法,这个方法中首先执行的是A中的foo方法,此时属于静态方法调用,static对应的类名就是明确指定的那个A类,故会输出A;然后是parent::foo()和self::foo()方法,这两个都属于转发调用,前一个调用的是B的foo方法,后一个调用的是C的foo方法,实际的执行内容都是static::foo(),当static::中的static其实是运行时所在类的别名,此时运行的类是C,所以都会输出C。
class Model
{
public static function find()
{
echo static::$name;
}
}
class Product extends Model
{
protected static $name = 'Product';
}
Product::find();
输出:
Product
分析:Product::find()方法运行的是Product继承自Model的find方法,这个方法中的static对应于此时正在执行的类名,即Product,所以相当于运行Product:: $name,输出了Product。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。