为了账号安全,请及时绑定邮箱和手机立即绑定

PHP关于静态绑定的一点疑问

PHP关于静态绑定的一点疑问

PHP
呼如林 2019-03-15 09:16:11
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(); 输出结果为ACC.我的疑问是为什么第二个是C而不是B?还请各位大神赐教
查看完整描述

3 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

自己来回答一下。静态调用分为转发调用和非转发调用。
转发调用:进行静态调用时使用static::,self::,parent::,forword_static_call进行调用。换句话说就是没有指定类名的静态条用。
非转发调用:进行静态调用时使用类名::或者进行非静态调用时使用类名->方法名调用。换句话说就是明确地指定类名的静态调用和非静态调用。

再说的通俗一点,顾名思义,非转发调用前面有类名所以调用的函数一定是属于“这个类的”,不需要转到别的类。转发调用就是由于前期的静态绑定导致在后面调用静态方法时可能“转发到其他的类”。

在PHP的官方文档里,对于后期静态绑定是这样说的:后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)中的类名。意思是当我们调用一个转发调用的静态调用时,实际调用的类是上一个非转发调用的类。
现在我一步步分析上面的例子
1.C::test().毫无疑问,这是一个非转发调用,因为::前面有类名C。
2.进入test()方法,有三个静态调用A::foo(),parent::foo(),self::foo(),对于这三个静态调用来说,他们的非转发调用类就是C。
3.现在执行A::foo(),这是一个非转发调用。A::foo()中的代码是static::who,这是一个转发调用,对于这个转发调用来说他的非转发调用类就是不再是C而是A(因为之前执行了A::foo())。因此执行的结果为A
4.现在执行parent::foo(),这是一个转发调用,转发到哪里呢?就是它的上一个非转发调用的类,也就是类C(在步骤2中提到的)。在这里一定要注意虽然在这之前执行了A::foo(),但是parent::foo()的上一个非转发调用的类任然是类C。因此执行的结果是C.
5.现在执行self::foo(),这个和parent::foo()一样都是转发调用,因此也输出C。

查看完整回答
反对 回复 2019-03-18
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

如果静态调用使用parent::或者 self::将转发调用信息,也就是运行时的调用者C

查看完整回答
反对 回复 2019-03-18
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

这就是静态调用static的意义啊.
你用parent或者self会显示 当前调用者 , 也就是C .
所以,才出现了static

查看完整回答
反对 回复 2019-03-18
  • 3 回答
  • 0 关注
  • 395 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信