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

PHP子类重声明私有变量不被父类函数识别的原因探究

PHP继承中私有/保护/公有成员的行为差异原理

这个现象的核心在于PHP对不同访问修饰符成员的可见性规则和绑定逻辑完全不同:

1. 私有(private)成员的本质:类级隔离

private成员的可见范围仅限于定义它的类内部,子类无法访问父类的private成员。你在DaughterClass里声明的private $variablePrivate,和父类的private $variablePrivate是两个完全独立的变量——它们只是名字相同,但属于不同的类,互相没有关联。

而父类的someFunction是在MotherClass中定义的,这个方法的代码逻辑属于父类,所以无论调用它的是父类对象还是子类对象,它访问的$this->variablePrivate只能是父类自己的私有成员。子类对象里的那个同名private变量,父类方法根本看不到。

2. 保护(protected)与公有(public)成员的本质:对象级继承

protected和public成员是可被继承的,它们的可见范围覆盖整个继承链。当子类重声明这两类成员时,实际上是在子类对象中覆盖了父类继承来的成员(或者说,子类的成员在对象属性链中优先级更高)。

父类的someFunction访问$this->variableProtected和$this->variablePublic时,$this指向的是当前调用的对象(子类对象),而这两类成员对父类方法是可见的,所以会直接读取子类重定义后的值。

结合代码验证

示例代码

class MotherClass {
    private $variablePrivate = 'original value';
    protected $variableProtected = 'original value';
    public $variablePublic = 'original value';
    public function someFunction() {
        echo '$this->variablePrivate: ' . $this->variablePrivate . '<br>';
        echo '$this->variableProtected: ' . $this->variableProtected . '<br>';
        echo '$this->variablePublic: ' . $this->variablePublic . '<br>';
    }
}
class DaughterClass extends MotherClass {
    private $variablePrivate = 'redeclared value';
    protected $variableProtected = 'redeclared value';
    public $variablePublic = 'redeclared value';
}
echo 'someFunction in MotherClass: <br>';
$mother = new MotherClass();
$mother->someFunction();
echo 'someFunction in DaughterClass: <br>';
$daughter = new DaughterClass();
$daughter->someFunction();

输出结果

someFunction in MotherClass:
$this->variablePrivate: original value
$this->variableProtected: original value
$this->variablePublic: original value
someFunction in DaughterClass:
$this->variablePrivate: original value
$this->variableProtected: redeclared value
$this->variablePublic: redeclared value

总结

  • private成员是类的“私有财产”,只有定义它的类自己能访问,子类的同名private变量是全新的独立变量;
  • protected/public成员属于对象的可继承属性,子类重定义后,整个继承链中的方法访问时都会使用子类的版本(只要当前对象是子类实例);
  • 父类的方法永远只能访问自己类定义的private成员,不管调用它的对象是父类还是子类实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:31:11