在传统的oop语言比如Java中,方法的重写Overriding和重载Overloading是多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写
(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
重载是一个类中,名称相同,但是参数类型或数目不同。
重写是子类中重新定义了跟父类的方法。
php不支持函数的重载,以后也不会支持,在经典oop语言比如java中,函数的重载有两个条件
1、参数的个数不同——php支持参数缺省,无法用参数个数区别
2、参数的类型不同——php是弱类型语言,会根据上下文自动做类型转换
所以,php手册中:PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法。主要通过魔术方法(magic
methods)来实现的,属性的重载主要由__set()、 __get()、__isset() 和
__unset()四个魔术方法来实现:1)void __set ( string
$name , mixed $value ),在给未定义的变量赋值时,__set() 会被调用。
2)mixed __get ( string $name ),读取未定义的变量的值时,__get() 会被调用。
3)bool __isset ( string $name ),当对未定义的变量调用isset() 或
empty()时,__isset() 会被调用。
4)void __unset ( string $name ),当对未定义的变量调用unset()时,__unset()
会被调用。
注意:属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。所以这些方法都不能被 声明为static
方法重载主要通过__call()和__callstatic()两个魔术方法来实现
1)mixed __call ( string $name , array $arguments
),当调用一个不可访问方法(如未定义,或者不可见)时,__call() 会被调用。
2)mixed __callStatic ( string $name , array $arguments
),当在静态方法中调用一个不可访问方法(如未定义,或者不可见)时,__callStatic() 会被调用。
例一:属性的重载
public function__set($name,$value) {
echo"Setting '$name' to '$value'\n";$this->data[$name] =$value;
}
public function__get($name) {
echo"Getting '$name'\n";
if (array_key_exists($name,$this->data)) {
return$this->data[$name];
}$trace=debug_backtrace();trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'] .' on line '.$trace[0]['line'],E_USER_NOTICE);
returnnull;
}public function__isset($name) {
echo"Is '$name' set?\n";
return isset($this->data[$name]);
}public function__unset($name) {
echo"Unsetting '$name'\n";
unset($this->data[$name]);
}public functiongetHidden() {
return$this->hidden;
}
}
echo"
\n"; $obj= newMemberTest; $obj->a=1;
echo$obj->a."\n\n"; var_dump(isset($obj->a));
unset($obj->a);var_dump(isset($obj->a));
echo"\n";
echo$obj->declared."\n\n";
echo"Let's experiment with the private property named 'hidden':\n";
echo"Privates are visible inside the class, so __get() not used...\n";
echo$obj->getHidden() ."\n";
echo"Privates not visible outside of class, so __get() is used...\n";
echo$obj->hidden."\n";?>
例二:方法的重载
public function__call($name,$arguments) {// 注意: $name 区分大小写echo"Calling object method '$name' ".implode(', ',$arguments)."\n";
}public static function__callStatic($name,$arguments) {// Note: value of $name is case sensitive.echo"Calling static method '$name' ".implode(', ',$arguments)."\n";
}
}$obj= newMethodTest;$obj->runTest('in object context'); MethodTest::runTest('in static context');// PHP 5.3.0之后版本?>
注意:__call()这个方法的主要功能是:在该类的实例调用一个不存在的方法时,执行该__call()方法。注意需要提前在类里声明:
function __call($fname,$argus)
{
echo
"你调用的方法:".$fname."不存在
";
echo "参数是".print_r($argus);
}
声明时包含两个参数,第一个参数是string型,是调用的不存在的方法的方法名($fname),第二个参数是
array型,是调用的不存在的方法的参数($argus)。