很多面试官在面试的时候都会问一些面向对象的问题。在面向对象的三大特性中,实现多态性最重要的方式就是方法重载和重写。但是在PHP中,只有重写,并没有完全的重载能力。重写,子类重写父类方法。//重写类A{publicfunctiontest($a){echo'ThisisA:'.$a,PHP_EOL;}}classchildAextendsA{publicfunctiontest($a){echo'ThisisAchild:'.$a,PHP_EOL;}}$ca=newchildA();$ca->test(1);这在PHP中是没有问题的,子类可以重写父类的方法。实例化子类时,调用子类实现的重写方法。重载,相同的方法名称但不同数量或类型的参数。A类{函数foo($a){回显$a;}//致命错误:无法重新声明A::foo()functionfoo($a,$b){echo$a+$b;}}不好意思,这样写结果会直接报错。PHP不支持这种重载功能。在PHP官方手册中,重载的定义是使用__set()、__get()、__call()、__callStatic()等魔术方法重载无法访问的变量或方法。这和我们在面向对象中学过的重载是完全不同的,很多人在手册中的注释中提出过质疑。当然,我们今天不谈这些法术的使用。它们的使用可以参考我们之前写的文章:PHP中的那些魔术方法(一)PHP中的那些魔术方法(二)那么,重载可以在PHP中实现吗?当然可以,但是会有点麻烦://OverloadclassB{publicfunctionfoo(...$args){if(count($args)==2){$this->fooAdd(...$args);}elseif(count($args)==1){echo$args[0],PHP_EOL;}else{echo'其他';}}privatefunctionfooAdd($a,$b){echo$a+$b,PHP_EOL;}}$b=newB();$b->foo(1);$b->foo(1,2);用一个方法调用其他方法,根据参数个数判断,可以实现参数个数不同的方法重载。//使用__call()重载类C{publicfunction__call($name,$args){if($name=='foo'){$funcIndex=count($args);如果(method_exists($this,'foo'.$funcIndex)){返回$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($参数[0]);}else{$this->fooInt($args[0]);}}}私有函数fooInt(int$a){echo$a.'是Int',PHP_EOL;}privatefunctionfooString(string$a){echo$a.'是字符串',PHP_EOL;}}$d=newD();$d->foo(1);$d->foo('1');反正上面方法实现的方法重载是很麻烦的,因为它会让某个方法或者魔法方法变得很重,需要变成一个controller根据参数调度内部方法。更多的情况下,我们还是应该使用不同的方法名,然后将public部分抽象成独立的private内部方法,实现不同方法名的“重载”。毕竟不同的语言还是需要掌握它们不同的性格,根据这些性格在我们的项目中灵活运用。测试代码: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============各媒体平台均可搜索【硬核项目经理】
