You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中抽象类构造函数获取子类属性值的原因及术语咨询

为什么PHP父类构造函数中会获取到子类的属性值?

首先先纠正下你代码里的两个小问题:parent是PHP的保留关键字,不能用作类名;子类名chile应该是child的笔误吧?不过这不影响核心问题的解释,我先把修正后的可运行代码贴出来:

abstract class ParentClass {
    protected $test = ['parent'];
    public function __construct() {
        die(var_dump($this->test));
    }
}

class ChildClass extends ParentClass {
    protected $test = ['child'];
}

new ChildClass(); // 实际输出: array(1) { [0]=> string(5) "child" }

核心原因与对应的PHP术语

这个现象的本质是属性覆盖(Property Overriding),再结合PHP中$this关键字的上下文特性导致的:

  1. 属性覆盖的本质:当子类定义了和父类同名的非静态属性时,子类的属性会隐藏父类的同名属性。这里的关键是,子类的属性并不是“替换”了父类的属性,而是在子类的实例中,同名属性的优先级更高。
  2. $this的上下文:在PHP中,$this始终指向当前正在操作的对象实例——哪怕是在父类的方法里。当你实例化ChildClass时,整个对象的本质是子类实例,只是继承了父类的方法。所以当父类构造函数执行$this->test时,它访问的是子类实例中已经初始化好的$test属性(也就是['child'])。

执行流程拆解

当你调用new ChildClass()时,PHP的执行顺序是这样的:

  • 第一步:初始化子类ChildClass的实例,此时子类的$test属性会被先赋值为['child']。
  • 第二步:因为子类没有定义自己的构造函数,PHP会自动调用父类的构造函数。
  • 第三步:父类构造函数中的$this指向的是已经初始化好的子类实例,所以访问$this->test时,自然拿到的是子类的属性值。

如何让父类构造函数获取自己的属性值?

如果想让父类构造函数访问自己的$test,不受子类覆盖的影响,可以把父类的属性设置为private:

abstract class ParentClass {
    private $test = ['parent']; // 改为private
    public function __construct() {
        die(var_dump($this->test)); // 此时输出['parent']
    }
}

class ChildClass extends ParentClass {
    protected $test = ['child']; // 这是子类独立的属性,和父类的$test互不干扰
}

new ChildClass();

因为private属性只能在定义它的类内部访问,子类无法覆盖这个属性,只能定义自己的同名属性(两者是完全独立的),所以父类构造函数中访问的就是自己的$test了。

内容的提问来源于stack exchange,提问作者Elegance accessory

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:49:19