概述
在java中,重载就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法,这也牵涉到了多态。
在PHP中呢,有人说php没有多态,那重载呢?
PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法,分为属性的重载和方法的重载;
我们是通过魔术方法(magic methods)来实现的,当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。本节后面将使用"不可访问属性(inaccessible properties)"和"不可访问方法(inaccessible methods)"来称呼这些未定义或不可见的类属性或方法。
属性重载
public void __set ( string $name , mixed $value )
public mixed __get ( string $name )
public bool __isset ( string $name )
public void __unset ( string $name )
在给不可访问的属性赋值时,__set() 会被调用。
读取不可访问的属性的值时,__get()会被调用。
当判断不可访问的属性是否存在的时候(使用isset(),empty())时,__isset()会被调用。
当对不可访问的属性执行销毁操作(unset())的时候,__unset()会被调用。
__get()方法,有两个参数,$name是指要操作的变量名称(另外三个都是这个意思),$value是指对应name的值。
一个很简单的例子:
class Person {
public $name;
private $age;
public function __set($name, $value)
{
echo "你赋值的属性{$name}不存在";
}
public function __get($name)
{
echo "你所访问的属性{$name}不存在";
}
public function __isset($name)
{
echo "你判断的属性{$name}不存在";
}
public function __unset($name)
{
echo "你销毁的属性{$name}不存在";
}
}
$person = new Person();
echo '赋值操作:',$person->gender = 'nale',<br />';
echo '取值操作:',$person->gender,'<br />';
echo 'isset判断操作:',isset($person->gender),'<br />';
echo 'empty判断操作:',empty($person->gender),'<br />';
echo 'empty判断操作:',empty($person->gender),'<br />';
echo 'unset操作:';unset($person->gender);
结果如下:
empty这里后面有个1是因为当前返回的是true,输出来就是1了;
当然,大家也会发现,没有这些魔术方法,我照样可以跑通,我把这些魔术方法注释掉:
class Person {
public $name;
private $age;
// public function __set($name, $value)
// {
// echo "你赋值的属性{$name}不存在";
// }
//
// public function __get($name)
// {
// echo "你所访问的属性{$name}不存在";
// }
//
// public function __isset($name)
// {
// echo "你判断的属性{$name}不存在";
// }
//
// public function __unset($name)
// {
// echo "你销毁的属性{$name}不存在";
// }
//
// public function __call($name, $arguments)
// {
// echo '你在调用不存在的方法';
// }
}
$person = new Person();
echo '赋值操作:',$person->gender = 123,'<br />';
echo '取值操作:',$person->gender,'<br />';
echo 'isset判断操作:',isset($person->gender),'<br />';
echo 'empty判断操作:',empty($person->gender),'<br />';
echo 'empty判断操作:',empty($person->gender),'<br />';
echo 'unset操作:';unset($person->gender);
echo '取值操作:',$person->gender,'<br />'; //访问不存在的属性,因为被销毁了,应该会报一个notic级别的错误
运行如下所示:
这个是因为在PHP中,并没有强制属性都在类中声明,这是动态的给对象属性赋值,在其它强类型语言中,可能行不通,所以在一般时候,并不建议这样写。
那如果有这种动态增加值的需求的时候怎么办呢,我们可以利用属性的重载来完成,如下:
class Person {
public $name;
private $age;
private $_attr = array();
public function __construct($name,$age)
{
$this->name = $name;
$this->age = $age;
}
public function __get($name)
{
if($this->_attr[$name]){
return $this->_attr[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
$this->_attr[$name] = $value;
}
public function __isset($name)
{
return isset($this->_attr[$name]);
}
public function __unset($name)
{
unset($this->_attr[$name]);
}
}
$person = new Person('lightWay', 24);
//赋值操作
$person->gender = 'male';
$person->home = 'hubei';
echo $person->home; //取值操作
unset($person->home); //销毁操作
方法重载
public mixed __call ( string $name , array $arguments )
public static mixed __callStatic ( string $name , array $arguments )
在对象中调用一个不可访问方法时,__call() 会被调用。
在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用。
$name 参数是要调用的方法名称。$arguments 参数是一个枚举数组,包含着要传递给方法 $name 的参数。
上代码说明吧:
class Person {
public function __call($name, $arguments)
{
echo '您正在调用一个不存在的方法',self::class,'::',$name,PHP_EOL;
print_r($arguments);
}
public static function __callStatic($name, $arguments)
{
echo '您正在调用一个不存在的静态方法',self::class,'::',$name,PHP_EOL;
print_r($arguments);
}
}
$person = new Person();
$person->sayMyInfo1('123',2,true);
$person::show(1,2,3);
执行结果如下:
我们可以用PHP中的重载,去模拟其他语言中的重载,代码如下:
class Person {
public $name;
public function __construct($name)
{
$this->name = $name;
}
public function __call($name, $arguments)
{
if($name == 'eating') {
switch (count($arguments)) {
case 1 :
echo "{$this->name}正在用{$arguments[0]}吃中餐",PHP_EOL;
break;
case 2 :
echo "{$this->name}正在用{$arguments[0]}和{$arguments[1]}吃西餐",PHP_EOL;
break;
case 0:
default:
echo "{$this->name}在喝西北风",PHP_EOL;
break;
}
} else {
echo '您访问的方法不存在';
}
}
}
$my = new Person('lightWay');
$my->eating('筷子');
$my->eating('刀','叉子');
$my->eating();
执行结果如下:
这里只是用了参数的不同,来执行不同的动作,可以利用的点很多,很多框架都会到这个,好吧,这里就完了,看完了,你还觉得PHP没用多态吗?
最后
以上就是爱笑嚓茶为你收集整理的php面向对象之重载(overloading)的全部内容,希望文章能够帮你解决php面向对象之重载(overloading)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复