多态是指在面向对象中能够根据使用类的上下文来重新定义或改变类的性质和行为。
PHP不支持重载实现多态,但是PHP可以变向的实现多态效果。如下:
<span style="color: #0000ff;">class</span><span style="color: #000000;"> a{ </span><span style="color: #0000ff;">function</span> test(<span style="color: #800080;">$i</span>){ <span style="color: #008000;">//</span><span style="color: #008000;"> $i可以是任何类型的变量</span> <span style="color: #008080;">print_r</span> <span style="color: #800080;">$i</span><span style="color: #000000;">; } }</span>
上例,可以看出由于PHP是弱类型语言,所以$i可以是任何类型的变量,这样一个函数就可以实现如java等强类型语言中靠改变参数类型重载方法的多态形式。
这种形式比JAVA的参数类型重载更便捷高效,但也存在问题,如下:
<span style="color: #000000;">php </span><span style="color: #008000;">/*</span><span style="color: #008000;">* 教师类有一个drawPolygon()方法需要一个Polygon类,用来画多边形,此方法内部调用多边形的draw()方法,但由于弱类型,我们可以传入Circle类,就会调用Circle类的draw方法,这就事与愿违了。甚至可以传入阿猫、阿狗类,如果这些类没有draw()方法还会报错。 </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Teacher{ </span><span style="color: #0000ff;">function</span> drawPolygon(<span style="color: #800080;">$polygon</span><span style="color: #000000;">){ </span><span style="color: #800080;">$polygon</span>-><span style="color: #000000;">draw(); } } </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Polygon{ </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> draw(){ </span><span style="color: #0000ff;">echo</span> "draw a polygon"<span style="color: #000000;">; } } </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Circle{ </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> draw(){ </span><span style="color: #0000ff;">echo</span> "draw a circle"<span style="color: #000000;">; } } </span>?>
可以看出这样灵活的多态,需要一些控制,在PHP5.3以后可以对参数做类型限制,如下:
<span style="color: #008000;">//</span><span style="color: #008000;"> 仿java,在变量参数前加一个限制类名</span> <span style="color: #0000ff;">function</span> drawPolygon(Polygon <span style="color: #800080;">$polygon</span><span style="color: #000000;">){ </span><span style="color: #800080;">$polygon</span>-><span style="color: #000000;">draw(); }</span>
这样就限制了只能传入Polygon及其子类。
还有一只是改变参数数量的重载,同样是因为PHP也不支持方法的重载,所以也需要些变通的方法实现,如下:
<span style="color: #000000;">php </span><span style="color: #008000;">//</span><span style="color: #008000;"> 通过可变参数来达到改变参数数量重载的目的 // 不是必须传入的参数,必须在函数定义时赋初始值</span> <span style="color: #0000ff;">function</span> open_database(<span style="color: #800080;">$DB</span>, <span style="color: #800080;">$cache_size_or_values</span>=<span style="color: #0000ff;">null</span>, <span style="color: #800080;">$cache_size</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">switch</span> (function_num_args()) <span style="color: #008000;">//</span><span style="color: #008000;"> 通过function_num_args()函数计算传入参数的个数,根据个数来判断接下来的操作</span> <span style="color: #000000;"> { </span><span style="color: #0000ff;">case</span> 1: <span style="color: #800080;">$r</span> = select_db(<span style="color: #800080;">$DB</span><span style="color: #000000;">); </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; </span><span style="color: #0000ff;">case</span> 2: <span style="color: #800080;">$r</span> = select_db(<span style="color: #800080;">$DB</span>, <span style="color: #800080;">$cache_size_or_values</span><span style="color: #000000;">); </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; </span><span style="color: #0000ff;">case</span> 3: <span style="color: #800080;">$r</span> = select_db(<span style="color: #800080;">$DB</span>, <span style="color: #800080;">$cache_size_or_values</span>, <span style="color: #800080;">$cache_size</span><span style="color: #000000;">); </span><span style="color: #0000ff;">break</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">return</span> <span style="color: #008080;">is_resource</span>(<span style="color: #800080;">$r</span><span style="color: #000000;">); } </span>?>