如何在子类中重写父类的构造方法
如何在子类中重写父类的构造方法
嘿,看来你在子类里重写父类构造方法的时候卡壳啦!别着急,结合你给出的父类代码片段,我给你拆解正确的做法,帮你解决问题~
首先先补全你那截断的父类构造逻辑(按常用的初始化逻辑合理补全),方便后续举例:
class Base extends \Core\Model { /** * Error messages * * @var array */ public $errors = []; public $errorMsg = ''; /** * Class constructor * * @param array $data initial property values * * @return void */ public function __construct($data = []) { foreach ($data as $key => $value) { // 父类逻辑:将传入的data属性赋值给类成员 if (property_exists($this, $key)) { $this->$key = $value; } } } }
接下来分两种常见场景讲子类的写法:
场景1:子类需要保留父类的初始化逻辑,同时添加自定义逻辑
这是最常用的情况,很多人踩坑的点就是忘记调用父类的构造方法,导致父类的属性没被正确初始化。
子类代码应该这么写:
class Child extends Base { // 子类专属属性 public $customAttr = ''; // 可以扩展参数,也可以和父类保持一致的签名 public function __construct($data = [], $customValue = '') { // 关键!先调用父类构造,执行父类的初始化逻辑 parent::__construct($data); // 这里写子类自己的初始化代码 $this->customAttr = $customValue; // 甚至可以覆盖父类的属性值 $this->errorMsg = '子类初始化的默认错误提示'; } }
解释:如果不调用parent::__construct($data),父类里的foreach循环不会执行,传入的$data不会被赋值到类属性上,$errors数组也只是默认的空数组,这大概率是你之前失败的原因!
场景2:子类完全不需要父类的构造逻辑,完全重写
如果你的子类有自己完全独立的初始化需求,不需要父类的逻辑,那可以直接写自己的构造方法,不用调用父类:
class Child extends Base { public function __construct() { // 完全自定义初始化逻辑 $this->errors = ['子类专属的错误列表']; $this->errorMsg = '完全重写后的错误提示'; } }
几个要注意的小细节
- 方法签名兼容性:如果父类构造有带默认值的参数,子类重写时尽量保持参数的兼容性。比如父类是
__construct($data = []),子类如果写成__construct($data)(没有默认值),那你实例化new Child()的时候就会报错,因为缺少必填参数。 - 参数传递要对应:调用
parent::__construct()的时候,要根据父类的参数要求传值,比如父类需要$data,你就传对应的变量,别漏传。
内容来源于stack exchange
相关产品推荐
相关产品推荐

