延迟静态绑定:static::非静态上下文使用及方法继承作用域疑问
PHP方法继承与延迟静态绑定的疑问解答
核心结论
- PHP里私有方法不会被继承,子类未重写私有方法时,父类中调用该私有方法的逻辑,本质是在父类作用域内访问自身的私有方法,并非把父类方法复制到子类。
- 私有方法的作用域固定属于定义它的类,不会因继承、调用上下文变化而改变。
代码示例与解析
先修正示例中的注释并补充执行结果:
<?php class A { private function foo() { echo "success!\n"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /* 子类B未重写foo(),父类test()中的调用始终指向A的私有foo(),因此执行成功 */ } class C extends A { private function foo() { /* 子类C重写了foo(),新foo()的作用域仅限C类内部 */ } } $b = new B(); $b->test(); // 输出:success! success! $c = new C(); $c->test(); // 执行失败:Fatal error: Uncaught Error: Call to private method C::foo() from context 'A'
逐场景拆解
场景1:B类实例调用test()
$this->foo():$this指向B实例,但test()是在A类中定义的,所以该调用处于A的作用域内,A可以直接访问自身的私有方法foo()。static::foo():static::是延迟静态绑定,会解析为当前运行时的类(即B),但B没有定义foo(),PHP不会复制A的私有方法到B,而是因为test()属于A,A有权限访问自己的foo(),因此最终还是调用A的foo()。
场景2:C类实例调用test()
$this->foo():$this指向C实例,C已经重写了私有foo(),此时test()在A的作用域内,A无法访问C的私有方法,同时C的重写覆盖了对A::foo()的隐式引用,因此报错。static::foo():static::解析为C类,C的foo()是私有方法,A的test()没有权限访问,直接触发致命错误。
内容的提问来源于stack exchange,提问作者AlexBor
相关产品推荐
相关产品推荐

