PHP面向对象:调用父类主方法时如何使用其父类子方法?
PHP继承中调用父类方法时强制使用父类实现的子类方法
问题代码
<?php class A { protected function subMethod() { return "A::subMethod"; } public function mainMethod(){ return 'calling ' . $this->subMethod(); } } class B extends A { protected function subMethod() { return "B::subMethod"; } public function caller(){ var_dump ('Using $this.. '. $this->mainMethod()); var_dump ('Using parent.. '. parent::mainMethod()); } } $b = new B(); $b->caller();
实际输出
"Using $this.. calling B::subMethod" "Using parent.. calling B::subMethod"
期望输出
"Using $this.. calling B::subMethod" "Using parent.. calling A::subMethod"
解决方案
PHP中parent::调用父类方法时,方法内部的$this仍指向当前子类实例,因此会优先调用子类重写的subMethod。以下是无需重复重写mainMethod的解决方案:
方案1:父类新增专用方法,明确调用自身实现
在父类A中新增方法,使用self::而非$this->调用subMethod,确保使用父类自身的实现:
class A { protected function subMethod() { return "A::subMethod"; } public function mainMethod(){ return 'calling ' . $this->subMethod(); } // 新增方法,强制使用父类的subMethod public function parentMainMethod() { return 'calling ' . self::subMethod(); } } class B extends A { protected function subMethod() { return "B::subMethod"; } public function caller(){ var_dump ('Using $this.. '. $this->mainMethod()); // 调用父类新增的专用方法 var_dump ('Using parent.. '. parent::parentMainMethod()); } }
方案2:给mainMethod添加参数控制逻辑
修改父类mainMethod,增加参数决定是否使用父类的subMethod,无需新增方法:
class A { protected function subMethod() { return "A::subMethod"; } public function mainMethod(bool $useParentSub = false){ $subMethodResult = $useParentSub ? self::subMethod() : $this->subMethod(); return 'calling ' . $subMethodResult; } } class B extends A { protected function subMethod() { return "B::subMethod"; } public function caller(){ var_dump ('Using $this.. '. $this->mainMethod()); // 传入true参数强制使用父类subMethod var_dump ('Using parent.. '. parent::mainMethod(true)); } }
方案3:直接调用父类的subMethod(适用于简单场景)
如果mainMethod逻辑仅为调用subMethod,可直接在子类中调用父类的subMethod:
class B extends A { protected function subMethod() { return "B::subMethod"; } public function caller(){ var_dump ('Using $this.. '. $this->mainMethod()); // 直接调用父类的subMethod var_dump ('Using parent.. calling ' . parent::subMethod()); } }
以上方案均无需在每个子类中重写mainMethod,避免了代码冗余,同时满足需求。
内容的提问来源于stack exchange,提问作者Alaa Mahmoud
相关产品推荐
相关产品推荐

