PHP 7中父类构造方法调用方式及代码修改咨询
嘿,我来帮你梳理清楚这个问题~首先可以明确地说:你当前Line A的写法是错误且不符合PHP规范的,必须修改,而且推荐用parent::__construct($label, $name)来替代。
接下来给你详细拆解原因和正确的做法:
为什么原写法不对?
在PHP 5及以后的版本(包括你用的PHP 7),构造方法的标准名称是__construct,而用AwesomeWorld::AwesomeWorld()这种类名重复的调用方式是PHP4的遗留写法,现在已经被废弃了,不仅语法上不被推荐,还可能导致未定义的行为(比如父类的属性没有正确初始化)。正确的父类构造调用方式
你的类继承链是HelloWorld → GoodWorld → AwesomeWorld,HelloWorld的直接父类是GoodWorld。在PHP里,调用直接父类的构造方法,最规范且健壮的写法是用parent::__construct(),它会自动找到当前类的直接父类的构造方法,不需要硬编码父类的类名。这样做的好处是:如果以后你的继承关系发生变化(比如HelloWorld改继承其他类),这段代码不需要修改就能正常工作,大大提升了代码的可维护性。
关于继承链的初始化顺序
当你在HelloWorld的构造里调用parent::__construct($label, $name)时,会先触发GoodWorld的构造方法,而GoodWorld的构造里又调用了parent::__construct()(也就是AwesomeWorld的构造),这样整个继承链的初始化逻辑都会被正确执行:- 先初始化AwesomeWorld的属性(label、name、visible等)
- 再初始化GoodWorld的inputType为'text'
- 最后HelloWorld再把inputType覆盖为'password'
这完全符合你代码里的预期逻辑。
如果想直接调用祖父类的构造?(不推荐)
如果你确实有特殊需求,想要跳过GoodWorld的构造直接调用AwesomeWorld的构造,那可以写AwesomeWorld::__construct($label, $name),但这种做法非常不推荐——因为GoodWorld的构造里可能有必要的初始化逻辑,跳过它会导致GoodWorld的属性无法正确设置,进而引发潜在的bug。
最后给你修改后的HelloWorld类代码示例:
class HelloWorld extends GoodWorld { public function __construct($label, $name) { parent::__construct($label, $name); // 修改后的Line A $this->inputType = 'password'; } public function draw() { $this->value = ''; parent::draw(); // 这里也建议改成parent::draw(),和构造方法的道理一样,避免硬编码父类名 } }
备注:内容来源于stack exchange,提问作者flash

