为何无法在PHP子类中覆盖父类常量?
为什么子类重写常量后,父类方法调用还是父类的常量?
这事儿的核心原因是你在父类的printHello()里用了self::HELLO——self是编译时绑定的,它只认自己代码所在的类,也就是MyClass,不管你实例化的是子类还是父类,self都会死死指向定义它的那个类。
举个直白的例子:你写self::HELLO的时候,PHP在编译阶段就把它绑定成了MyClass::HELLO,哪怕你后来用子类实例调用这个方法,它也不会改主意。
那要怎么拿到子类的常量呢?用static关键字就行!static是运行时绑定的,它会看实际被实例化的那个类是谁。把父类里的self换成static,代码改成这样:
namespace App; class MyClass { const HELLO=__CLASS__; public function printHello() { echo(static::HELLO); // 替换self为static } }
这时候再运行你的测试代码:
$class = new \App\MyClass2(); $class->printHello();
输出就会是你预期的App\MyClass22了。
总结下:self看的是「这段代码写在哪个类里」,static看的是「运行时实际用的是哪个类」——这就是PHP的延迟静态绑定特性,专门用来解决子类重写父类成员后,父类方法能正确调用子类成员的场景。
内容的提问来源于stack exchange,提问作者Dimitrios Desyllas
相关产品推荐
相关产品推荐

