本文中的PHP版本:PHP Version 7.2.5
从文章中的标题名字的定义提取出两个关键点,第一点静态,也就是说这个功能只适用于静态属性或静态方法。第二点延迟绑定。
类可以自下往上调用父类方法,如果需要在父类中根据不同的子类,来调用子类的方法,那么就需要延迟静态绑定。延迟静态绑定用的是保留关键词static
所谓延迟静态绑定,顾名思义,静态调用时::符号左侧的部分的的绑定是延迟,也就是说不再被解析为定义当前方法所在的类,而是在实际运行时计算的
话不多说 直接上代码:
class People { public static function hungry() { static::eat(); //static和调用它的类进行静态绑定,然后调用static所绑定的类 的eat方法 } public static function eat() { echo __CLASS__." is eat"; } } class Zack extends People { public static function hungry() { parent::hungry(); } public static function eat() { echo __CLASS__." is eat \n"; } } class Duke extends People { public static function hungry() { parent::hungry(); } public static function eat() { echo __CLASS__." is eat \n"; } } /** 代码执行流程 运行代码之后 先执行Zack::hungry()方法 然后这个方法里面又去调用了父类的hungry()方法 然后父类的hungry()方法内部发现是一个static延迟调用 因为此时调用者是Zack类 所以父类hungry()方法里面的static::eat() 就会去调用Zack::eat() 通俗来说 在这段代码中 父类hungry()方法里面的static::eat() 就等于Zack::eat() */ Zack::hungry(); //输出:Zack is eat /** 代码执行流程 运行代码之后 先执行Duke::hungry()方法 然后这个方法里面又去调用了父类的hungry()方法 然后父类的hungry()方法内部发现是一个static延迟调用 因为此时调用者是Duke类 所以父类hungry()方法里面的static::eat() 就会去调用Duke::eat() 通俗来说 在这段代码中 父类hungry()方法里面的static::eat() 就等于Duke::eat() */ Duke::hungry(); //输出:Duke is eat
如果将上面代码中的第5行的static::eat();换成self::eat(); 运行就是绑定的当前方法所在的类,而不是静态调用的类。最终输出的结果如下:
People is eat
People is eat
注意:只有在使用以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()和forward_static_call_array()时才会进行转发调用。转发调用即将当前的调用者传递给后面调用的方法。
以官网的实例来解释一下:
class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."<br/>"; } } class B extends A { public static function test() { //通过类名进行调用,是非转发调用,调用者是A A::foo(); //parent和self均是转发调用,将调用者C进行转发,所以调用者还是C parent::foo(); self::foo(); } public static function who() { echo __CLASS__."<br/>"; } } class C extends B { public static function who() { echo __CLASS__."<br/>"; } } C::test();
通过self::,parent::,static:: 以及 forward_static_call()和forward_static_call_array()调用时,调用者会被继续转发。故以上代码运行之后会输出:
A
C
C
可以在项目中自行挖掘使用场景,比如一个会员父类 class Vip
下面两个子类分别是 超级会员 svip 和 年费会员 yvip
可以在两个子类中分别重写 static usergroup() 方法 或者其他静态属性 ,父类中使用延迟静态绑定
这样可以写出很优雅的代码
无论从事什么行业,只要做好两件事就够了,一个是你的专业、一个是你的人品,专业决定了你的存在,人品决定了你的人脉,剩下的就是坚持,用善良专业和真诚赢取更多的信任。
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。
精彩评论