重写,子类重写父类方法

//重写classA{publicfunctiontest($a){echo'ThisisA:'.$a,PHP_EOL;}}classchildAextendsA{publicfunctiontest($a){echo'ThisisAchild:'.$a,PHP_EOL;}}$ca=newchildA();$ca->test(1);

这个在PHP中是没有任何问题的,子类可以重写父类的方法。
当实例化子类的时候,调用的便是子类实现的重写的方法。

重载,相同方法名但参数数量或者类型不同。

php重载PHP中的重载是个啥 CSS

classA{functionfoo($a){echo$a;}//Fatalerror:CannotredeclareA::foo()functionfoo($a,$b){echo$a+$b;}}

抱歉,这样写的结果将会是直接的报错。
PHP并不支持这样的重载能力。
而在PHP的官方手册上,重载的定义是利用__set()、__get()、__call()、__callStatic()等魔术方法来对无法访问的变量或方法进行重载。
这与我们所学习的面向工具中的重载完备不同,在手册中的note里也有很多人对此提出了疑问。
当然,我们本日并不会再去讲这些魔术方法的利用。
关于它们的利用可以参考我们之前写过的文章:PHP中的那些魔术方法(一)、PHP的那些魔术方法(二)

那么,在PHP中可以实现重载吗?当然可以,只不过会麻烦一些:

//重载classB{publicfunctionfoo(...$args){if(count($args)==2){$this->fooAdd(...$args);}elseif(count($args)==1){echo$args[0],PHP_EOL;}else{echo'other';}}privatefunctionfooAdd($a,$b){echo$a+$b,PHP_EOL;}}$b=newB();$b->foo(1);$b->foo(1,2);

利用一个方法来调用其他方法,根据参数数量来进行判断,就可以实现参数数量不同的方法重载。

//利用__call()进行重载classC{publicfunction__call($name,$args){if($name=='foo'){$funcIndex=count($args);if(method_exists($this,'foo'.$funcIndex)){return$this->{'foo'.$funcIndex}(...$args);}}}privatefunctionfoo1($a){echo$a,PHP_EOL;}privatefunctionfoo2($a,$b){echo$a+$b,PHP_EOL;}privatefunctionfoo3($a,$b,$c){echo$a+$b+$c,PHP_EOL;}}$c=newC();$c->foo(1);$c->foo(1,2);$c->foo(1,2,3);

利用__call()魔术方法或许会更大略,但也会让一些新手在接手项目的时候蒙圈。
毕竟魔术方法对IDE是不友好的,这样的开拓让__call()成为了一个模板方法,由它来定义操作的算法骨架。
我们也可以根据参数类型来仿照重载能力。

//参数类型不同的重载classD{function__call($name,$args){if($name=='foo'){if(is_string($args[0])){$this->fooString($args[0]);}else{$this->fooInt($args[0]);}}}privatefunctionfooInt(int$a){echo$a.'isInt',PHP_EOL;}privatefunctionfooString(string$a){echo$a.'isString',PHP_EOL;}}$d=newD();$d->foo(1);$d->foo('1');

不管怎么说,用上述方法实现的方法重载都非常麻烦,由于会让某一个方法或者魔术方法非常重,它须要成为一个掌握器来根据参数对内部的方法进行调度。
更多的情形下,我们该当还是利用不同的方法名然后抽象公共的部分提取成独立的私有内部方法来实现不同方法名的“重载”。
毕竟不同的措辞还是要节制它们不同的个性,并且根据这些个性灵巧地利用在我们的项目中。

测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/201912/source/PHP%E4%B8%AD%E7%9A%84%E2%80%9C%E9%87%8D%E8%BD%BD%E2%80%9D%E6%98%AF%E4%B8%AA%E5%95%A5%EF%BC%9F.php

参考文档: https://www.php.net/manual/zh/language.oop5.overloading.php#77843