PHP构造函数属性提升下子类可访问私有变量?我的理解有误吗?
关于PHP构造函数属性提升的私有属性访问问题解析
你代码里的情况根本不是子类能访问父类私有属性,而是你误解了构造函数属性提升的作用和私有属性的作用域:
子类
Child的构造函数里用private $private做属性提升,本质是在子类内部直接声明了一个属于子类自己的私有属性$private,和父类的私有属性$private是两个完全独立的变量,只是名字相同而已。私有属性的作用域仅限定义它的类,父类的私有属性子类本来就碰不到,你这里访问的是子类自己的那个,所以完全正常。另外纠正一个误区:构造函数属性提升不会自动调用父类构造函数。你子类的构造函数完全覆盖了父类的,没写
parent::__construct(),所以父类的$protected和$private根本没被初始化,子类用的是自己定义的$protected(protected属性子类可以继承访问,所以这个和父类的$protected是同一个)以及自己的$private。
如果想正确实现继承并使用属性提升,应该这么写:
// 注意:Parent是PHP关键字,不能用作类名,这里改成ParentClass class ParentClass { public function __construct( protected $protected, private $private ) { } } class Child extends ParentClass { // 子类如果需要自己的私有属性,换个名字,或者不要重复定义父类的私有属性 public function __construct( protected $protected, private $childPrivate ) { // 必须手动调用父类构造函数,初始化父类的属性 parent::__construct($protected, '父类私有属性的初始化值'); } function myFunc() { // echo $this->private; // 这里会直接报错,父类私有属性子类访问不到 echo $this->protected; // 正常,protected属性子类可访问 echo $this->childPrivate; // 访问子类自己的私有属性,没问题 } }
简单来说,你遇到的不是属性提升的问题,是对私有属性作用域的理解偏差。属性提升只是语法糖,不会改变PHP的类属性访问规则,子类里的私有属性是自己的,和父类同名私有属性无关,所以能访问是合理的。
内容的提问来源于stack exchange,提问作者Arturo Verbel De León
相关产品推荐
相关产品推荐

