在面向对象语言中,有一个很重要的概念——overload,即重载。所谓重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。但是,在php中,这个概念跟大多面向对象语言中的“重载”一点关系都没有,根本就是风马牛不相及的。

php中的重载,是指动态地"创建"类属性和方法。当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。再说的直白点,就是访问一个类或者对象的不可访问的属性或者方法的时候的一种处理机制。(不可访问,比如不存在或者因访问关键字的限制而不能访问)

1、属性重载

四个魔术方法:

1)__get($属性名)

  访问对象中不可访问的属性的时候,会自动调用该方法  

2)__set($属性名,$属性值)

  给对象中不可访问的属性赋值的时候,会自动调用该方法。方法中的两个参数,依次代表所访问的属性和对应的值。

3)__isset($属性名)

  当对一个对象不可访问的属性进行isset()或者empty()判断的时候,会自动调用该方法。

4)__unset($属性名)

  当对一个对象不可访问的属性进行unset()销毁的时候,会自动调用该方法。

使用的代码如下:

<?php
header("Content-type:text/html;charset = utf-8"); class Test{
public $p1 = 1; function __get($property) {//访问不可访问属性的时候,会自动调用该方法
echo "不可访问的属性:{$property}";
} function __set($property,$value) {//对不可访问的属性赋值,会自动调用该方法
echo "对不可访问的属性{$property} 赋值 {$value}<br/>";
} function __isset($property){//对不可访问的属性进行isset判断,会自动调用该方法
echo "对不可访问的属性{$property}进行isset判断<br/>";
} function __unset($property){//对不可访问的属性进行unset操作,会自动调用该方法
echo "对不可访问的属性{$property}进行unset操作<br/>";
}
} $t = new Test();
echo $t->p1."<br/>";
echo $t->p2."<br/>"; //给不可访问的属性进行赋值
$t->p3 = 2; //对不可访问的属性进行isset判断
isset($t->p4); //对不可访问的属性进行unset操作
unset($t->p5); /*
运行结果:
1
不可访问的属性:p2
对不可访问的属性p3 赋值 2
对不可访问的属性p4进行isset判断
对不可访问的属性p5进行unset操作
*/
?>

配合是用__get()和__set()方法,可以使类变得更加灵活和自由,可以很方便给类添加属性。如下:

<?php
header("Content-type:text/html;charset = utf-8"); class Test{
//定义数组,用于存储不可访问的属性
protected $plist = array(); function __get($property) {//访问不可访问属性的时候,会自动调用该方法
//属性不可访问,从plist中读取
if (isset($this->plist[$property])) {
return $this->plist[$property];
}
else {
return "属性{$property}不可访问";
}
} function __set($property,$value) {//对不可访问的属性赋值,会自动调用该方法
//属性不可访问,将之存放到plist中
$this->plist[$property] = $value;
} function __isset($property){//对不可访问的属性进行isset判断,会自动调用该方法
$v = isset($this->plist[$property]);
return $v;
} function __unset($property){//对不可访问的属性进行unset操作,会自动调用该方法
unset($this->plist[$property]);
}
} $t = new Test();
$t->p1 = 1;//对不可访问的属性赋值
echo "不可访问的属性p1的值为:".$t->p1."<br/>";//使用p1属性(经过上一行代码,p1已经添加到了plist中) echo "不可访问的属性p2的值为:".$t->p2."<br/>";//没对p2赋值过 //分别对p1和p2进行isset操作
$r1 = isset($t->p1);//结果为true,但是如果不处理__isset魔术方法,将返回false
$r2 = isset($t->p2);//结果为false,本来也不存在...
var_dump($r1);echo "<br/>";
var_dump($r2);echo "<br/>"; //分别对p1和p2进行unset操作
unset($t->p1);
unset($t->p2);
echo "不存在的属性p1的值为:".$t->p1."<br/>";
echo "不存在的属性p2的值为:".$t->p2."<br/>"; /*
结果:
不可访问的属性p1的值为:1
不可访问的属性p2的值为:属性p2不可访问
bool(true)
bool(false)
不可访问的属性p1的值为:属性p1不可访问
不可访问的属性p2的值为:属性p2不可访问
*/
?>

2、方法重载

1)__call()

  调用对象的不可访问的方法的时候,会自动调用该方法。

2)__callstatic()

  调用类的不可访问的静态方法的时候,会自动调用该方法。

示例:

<?php
header("Content-type:text/html;charset = utf-8"); class Test {
/*
@desc 调用不存在的成员方法的时候,会自动调用该方法
@param $name,方法名
@param $args,方法参数
*/
function __call($name,$args){
echo "调用不存在的方法{$name}";
}
} $t1 = new Test();
$t1->f1();
echo "<br />";
$t1->f2(); /*
结果:
调用不存在的方法f1
调用不存在的方法f2
*/
?>

实例:利用php的方法重载来实现面向对象中通用的重载,即一个类内多个方法的方法名相同但是参数不同

设计一个打招呼的方法,至少输入一个参数(人名)

输入一个参数,输出:hello,xx;

输入两个参数,输出:hello,xx,yy;

输入三个及以上参数,输出:hello,guys;

<?php
header("Content-type:text/html;charset = utf-8"); class Test {
/*
@desc 调用不存在的成员方法的时候,会自动调用该方法
@param $name,方法名
@param $args,方法参数
*/
function __call($name,$args){
if ($name === "sayHello") {//处理未定义方法sayHello
$n = count($args);
if ($n<1) {
trigger_error("There's zero params!!!!");
}
else if ($n == 1) {
echo "hello,{$args[0]}<br/>";
}
else if ($n == 2) {
echo "hello,{$args[0]},{$args[1]}<br/>";
}
else {
echo "hello,guys!<br/>";
}
}
}
} $t1 = new Test();
$t1->sayHello();
$t1->sayHello("Richard");
$t1->sayHello("Maria","Robert");
$t1->sayHello("Maria","Robert","Richard"); /*
结果: Notice: There's zero params!!!! in /Users/xx/xx/xx/xx.php on line 14
hello,Richard
hello,Maria,Robert
hello,guys!
*/
?>

php中的重载以及几个常用的魔术方法示例的更多相关文章

  1. php面向对象类中常用的魔术方法

    php面向对象类中常用的魔术方法   1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct( ...

  2. Python | Python常用函数、方法示例总结(API)

    目录 前言 1. 运算相关 2. Sring与数字 3. 列表相关 4. 集合相关 5. 序列化类型 6. 字典相关 7. 输入输出 8. 文件相关 9. json模块 10. unittest测试模 ...

  3. PHP中常用的魔术方法

    我们在PHP中经常用到魔术方法,像构造方法,析构方法等等魔术变量,下面总结一下一些常用的魔术变量: __construct(),__destruct(),__clone(),__autoload(), ...

  4. PHP序列化、反序列化常用的魔术方法

    __wakeup() //使用unserialize时触发__sleep() //使用serialize时触发__destruct() //对象被销毁时触发__call() //在对象上下文中调用不可 ...

  5. PHP常用的魔术方法及规则

    1. __construct 具有构造函数的类会在每次创建新对象时先调用此方法;初始化工作执行.2. __desstruct 对象的所有引用都被删除或者当对象被显式销毁时执行.3.__call()在对 ...

  6. php常用的魔术方法

    __construct:构造函数,一旦创建对象都就会自动调用 __call:当调用了未定义的方法时会自动触发 __set:当给类外部不可访问的属性设置值时会自动触发 __get:当获取类外部不可访问的 ...

  7. PHP面向对象中常用的关键字和魔术方法

    PHP面向对象中常用的关键字 final        1.final不能修饰成员属性(类中常量不是用这个关键字)        2.final只能修饰类和方法 作用:            使用fi ...

  8. php中的常用魔术方法总结

    以下是对php中的常用魔术方法进行了详细的总结介绍,需要的朋友可以过来参考下 常用的魔术方法有:__Tostring () __Call() __autoLoad() __ clone() __GET ...

  9. java中的重载与重写

    重载简述 在java语言中,同一个类中的两个或者两个以上的方法可以有同一个名字,只要他们的的参数声明不同即可,该方法被称为重载,这个过程称为方法的重载,它是实现java多态性的一种方式. 重载是友好的 ...

随机推荐

  1. GCDAsyncSocket类库,IOS下TCP通讯使用心得

    关于在IOS下使用Socket进行通讯的技术文章也许诺很久了,今日又是一个还债的日子,网上虽然很多介绍过AsyncSocket或GCDAsyncSocket的文章,但其实就那么一两篇大部分都是转载,于 ...

  2. python基础之递归,匿名,内置函数

    递归函数: 什么是递归函数? 函数递归调用:在调用一个函数的过程中,又直接或间接地调用了该函数本身. 递归必须要有两个明确的阶段: ①递推:一层一层递归调用下去,强调:每进入下一层问题规模减少 ②回溯 ...

  3. WPF中的动画——(五)路径动画

    路径动画是一种专门用于将对象按照指定的Path移动的动画,虽然我们也可以通过控制动画的旋转和偏移实现对象的移动,但路径动画更专业,它的实现更加简洁明了. 路径动画中最常用的是MatrixAnimati ...

  4. Inno Setup入门(二十一)——Inno Setup类参考(7)

    复选框 复选框(CheckBox)用于多个并不互斥的几个选项中作出一个或者多选择,例如字体可以有粗体.斜体和下划线,这三种状态可以任意组合,像这样的选项可以采用复选框实现.Pascal脚本中对应的类是 ...

  5. mysql的锁定问题

    1.锁定这个问题,是mysql自动产生的,不用程序猿自己加锁 答:默认情况下,档执行insert/update操作时,mysql会自动进行表锁定.从而此时读取操作只能等待. 2.mysql, 需要添加 ...

  6. Atlassian发布JIRA项目组合管理解决方案

    在其年度用户峰会上,开发和协作软件供应商Atlassian发布了JIRA Portfolio,JIRA Portfolio是JIRA的一个附加组件"可以提供简单准确的视图用于计划和管理跨团队 ...

  7. Ubuntu下Wine使用教程

    转自:http://blog.csdn.net/wangchangshuai0010/article/details/12057251 用了段时间的Ubuntu,感觉很好!可是工作的时候还是要用到 w ...

  8. 某游戏研究之字符过滤类-WorldFilter

    所谓字符过滤器,常常用在聊天的内容,比如一连串的骂人难听的话,我们要屏蔽掉,避免造成不好的东西! 当然我作为中华天朝一个有文明有素质的人,肯定偶尔会做这样的事情啦,特别是打LOL的时候,算了不讲了,都 ...

  9. 关于V1.6.0版本的项目总结

    10月28号,我们开了1.6项目的总结大会,包括Ting总在内,前端.后台.运维都来参加总结大会了.虽然目标基本达成,但同时也暴露出很多问题,我们希望各方能够坐下来总结一下自己或者各个相关团队的功过是 ...

  10. 将具有特殊class名img标签替换成[img][/img]标签--javascript正则表达式实践

    在项目中,可能有时候需要将一些特殊的东西加一个特别的属性,或者一个特殊的Class.如下: <!-- 第一种写法 --> <img src="abc.jpg" f ...