PHP的重载与覆盖及魔术方法使用

来自技术开发小组内部wiki
2015年1月5日 (一) 11:07卢少锦讨论 | 贡献的版本

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至: 导航搜索

重载(overload),是发生在同一类中(与什么父类子类、继承毫无关系)  

方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载overload是一个类中多态性的一种表现。

覆盖(override),  是发生在子类中,(也就是说必须有继承的情况下才有覆盖发生)   

子类继承一个类,也就有了父类了全部方法,如果功能要变,那就把那个函数在子类中重新实现一遍。覆盖override也是一个类多态性的一种表现

严格意义上讲:重载必须函数名相同,参数在类型或者参数个数上必须有所不同,子类中具有与父类相同的返回类型及参数表,子类方法覆盖父类方法

PHP是弱类型语言,不支持严格意义上的重载,重写则对参数类型和个数也没有严格要求。

重写实例:

<?php

class Animal{

$height = 1;

public function eat($energy){

$this->height = $this->height+$energy/1000;

}

}

class Cat extend Animal{

public function eat($energy){

$this->height = $this->height+energy/2000;

}

}

$smallCat = new Cat();

$energy= 1000;

$smallCat->eat($energy);

?>

由于PHP不支持重载,但是可以曲线救国,实现方法就是使用PHP5.3的新特性:魔术方法__call(),__callStatic()

重载实例:

<?php

class Cat{

public $height = 1;

public $weight = 1;

public function __call($name,$arg){

$count = count($arg);

if($count>0){

switch($count){

case 1:

$this->height++;

break;

case 2:

$this->height++;

$this->weight++;

break;

default :

$this->height = $this->height+2;

$this->weight = $this->weight+2;

break;

}

}

}

}

$smallCat = new Cat();

$fruit = 1;

$meat = 1;

$smallCat->eat($fruit);

$smallCat->eat($fruit,$meat);

}

?>

如果是静态调用使用__callStatic,用法同上

__call 当要调用的方法不存在或权限不足时,会自动调用__call 方法。

__callStatic 当调用的静态方法不存在或权限不足时,会自动调用__callStatic方法。


__call($funcname, $arguments)

__callStatic($funcname, $arguments)


参数说明:

$funcname String 调用的方法名称。

$arguments Array 调用方法时所带的参数。

__call 例子


  1. <?php  
  2.   
  3. class Member{  
  4.   
  5.     protected $memberdata = array();  
  6.   
  7.     public function __call($func$arguments){  
  8.         list($type$name) = explode('_'$func);  
  9.       
  10.         if(!in_array($typearray('set','get')) || $name==){  
  11.             return ;  
  12.         }  
  13.   
  14.         switch($type){  
  15.             case 'set':  
  16.                 $this->memberdata[$name] = $arguments[0];  
  17.                 break;  
  18.               
  19.             case 'get':  
  20.                 return isset($this->memberdata[$name])? $this->memberdata[$name] : ;  
  21.                 break;  
  22.               
  23.             default:  
  24.         }  
  25.   
  26.     }  
  27.   
  28. }  
  29.   
  30.   
  31. class User extends Member{  
  32.   
  33.     public function show(){  
  34.         if($this->memberdata){  
  35.             foreach($this->memberdata as $key=>$member){  
  36.                 echo $key.':'.$member.'<br>';  
  37.             }  
  38.         }  
  39.     }  
  40.   
  41. }  
  42.   
  43.   
  44. class Profession extends Member{  
  45.   
  46.     public function show(){  
  47.         if($this->memberdata){  
  48.             foreach($this->memberdata as $key=>$member){  
  49.                 echo $key.':'.$member.'<br>';  
  50.             }  
  51.         }  
  52.     }  
  53.   
  54. }  
  55.   
  56. $userobj = new User();  
  57. $userobj->set_name('fdipzone');  
  58. $userobj->set_age(29);  
  59. $userobj->show();  
  60.   
  61. $probj = new Profession();  
  62. $probj->set_profession('IT SERVICE');  
  63. $probj->set_price(2500);  
  64. $probj->show();  
  65.   
  66. ?>  

_callStatic例子


  1. <?php  
  2.   
  3. class Member{  
  4.   
  5.     protected static $memberdata = array();  
  6.   
  7.     public static function __callStatic($func$arguments){  
  8.   
  9.         list($type$name) = explode('_'$func);  
  10.           
  11.         if(!in_array($typearray('set','get')) || $name==){  
  12.             return ;  
  13.         }  
  14.   
  15.         $feature = get_called_class(); //获取静态方法调用的类名
  16.   
  17.         switch($type){  
  18.             case 'set':  
  19.                 self::$memberdata[$feature][$name] = $arguments[0];  
  20.                 break;  
  21.   
  22.             case 'get':  
  23.                 return isset(self::$memberdata[$feature][$name])? self::$memberdata[$feature][$name] : ;  
  24.                 break;  
  25.   
  26.             default:  
  27.         }  
  28.       
  29.     }  
  30.   
  31. }  
  32.   
  33.   
  34. class User extends Member{  
  35.   
  36.     public static function show(){  
  37.   
  38.         $feature = get_called_class();  
  39.   
  40.         if(self::$memberdata[$feature]){  
  41.             foreach(self::$memberdata[$featureas $key=>$member){  
  42.                 echo $key.':'.$member.'<br>';  
  43.             }  
  44.         }  
  45.     }  
  46.   
  47. }  
  48.   
  49.   
  50. class Profession extends Member{  
  51.   
  52.     public static function show(){  
  53.   
  54.         $feature = get_called_class();  
  55.   
  56.         if(self::$memberdata[$feature]){  
  57.             foreach(self::$memberdata[$featureas $key=>$member){  
  58.                 echo $key.':'.$member.'<br>';  
  59.             }  
  60.         }  
  61.     }  
  62.   
  63. }  
  64.   
  65. User::set_name('fdipzone');  
  66. User::set_age(29);  
  67. User::show();  
  68.   
  69. Profession::set_profession('IT SERVICE');  
  70. Profession::set_price(2500);  
  71. Profession::show();  
  72.   
  73. ?>