侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP面向对象程序设计重载(overloading)操作详解

php  /  管理员 发布于 7年前   166

本文实例讲述了PHP面向对象程序设计重载(overloading)操作。分享给大家供大家参考,具体如下:

重载

PHP中的”重载”与其它绝大多数面向对象语言不同,只是他们都是用的相同的名词而已。传统的”重载”是用于提供多个同名的 类方法,但各方法的参数类型和个数不同。 PHP所提供的”重载”(overloading)是指动态地”创建”类属性和方法。当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。是通过魔术方法(magic methods)来实现的。

一般来说,把类中的成员属性都定义为private的,这更符合现实的逻辑,能够更好的对类中成员起到保护作用。但是,对成员属性的读取和赋值操作是非常频繁的,而如果在类中为每个私有属性都定义可以在对象的外部获取和赋值的公有方法,又是非常非常烦恼的。因此在PHP5.1.0以后的版本中,预定义了两个方法“__get()”和“__set()”,用来完成对所用私有属性都能获取和赋值操作,以及用来检查私有属性是否存在的方法“__isset()”和用来删除对象中私有属性方法“__unset()”。
通俗一点来说,重载在php中的含义是指,当一个对象或类使用其未定义或不可见的属性和方法时,其中的一些“处理机制”。

属性重载

对一个对象不存在的属性进行使用时,这个类中预先设定好的应对办法(处理机制)。

属性,本质就是变量,其只有4个操作:

取值:

当对一个对象不存在(未定义或不可见)的属性进行“取值”时,就会自动调用方法:__GET()方法不区分大小写。

赋值:

当对一个对象不存在(未定义或不可见)的属性进行“赋值”时,就会自动调用方法:__SET()

判断(isset):

当对一个对象不存在(未定义或不可见)的属性进行isset()判断时,就会自动调用方法:isset()

销毁(unset):

当对一个对象不存在的(未定义或不可见)属性进行unset()判断时,就会自动调用方法:unset()

以上4个方法,被称为魔术方法。

魔术方法

__GET($属性名):

在对一个对象不存在的属性进行“取值”的时候,会自动调用的方法,其中该方法可以带一个形参,表示要对之取值而又不存在的属性名(字符串),可以使用该方法对意外情况进行某种特殊的处理。

例如:

p1; //1echo $a1->p2; //未定义$p2,会报错, Notice: Undefined property: A::$p2?>

php的重载,使用__get()方法对上面的出错作“优雅处理”。

{$prop_name}属性还未定义(不存在)!";    return ""; //也可以返回0,或false等    */    //还可以这样处理    trigger_error("发生错误:属性不存在!", E_USER_ERROR);    die();  }}$a1 = new A();echo $a1->p1; //1echo $a1->p2; //未定义$p2,但经过"处理"?>

这里举一个对所用私有属性获取的操作的例子。

例子:

name = $name;    $this->sex = $sex;    $this->age = $age;  }  private function __get($propertyName){ //这里要用private修饰,防止类外部调用    if($propertyName == 'age'){      return $this->age;    }  }}$p = new Person('yeoman', '男',23);$v1 = $p->name;$v2 = $p->sex;$v3 = $p->age;  //自动调用了__get()方法获取私有属性age(函数定义里面返回)echo "name=$v1, sex=$v2, age=$v3";?>

运行结果为:

name=yeoman, sex=男, age=23

__SET($属性名, 值):

当对一个对象不存在的属性进行“赋值”时,就会自动调用这个内部的魔术方法;其有2个形参,分别代表要对不存在的属性进行赋值的“属性名”和“属性值”。
这个方法,结合_GET方法,往往可以使我们定义的类,有一种可扩展的特性。即:类或对象的属性,可以更为方便自由。

例子:

prop_list[$p] = $v;  }  function __get($p){    return $this->prop_list[$p];  }}$a1 = new A();$a1->p1 = 1;  //不存在的属性名赋值,此时会调用_set(),并传过去"p1"和1$a1->p2 = 2;$a1->ac = 'avc';echo "
输出这些“不存在的属性”的值:";echo "
a1->p1:" . $a1->p1; //不存在的属性名取值,此时会调用_get(),并传过去"p1"echo "
a1->p2:" . $a1->p2;echo "
a1->ac:" . $a1->ac;?>

运行结果为:

输出这些“不存在的属性”的值:
a1->p1:1
a1->p2:2
a1->ac:avc

__ISSET($属性名):

当对一个对象不存在的属性进行isset()判断时,就会自动调用内部方法:isset();

用法:

$v1 = isset($对象->不存在的属性);  //此时会调用这个对象所属类中的魔术方法:isset()

例子:

prop_list[$p] = $v;  }  function __get($p){    if($this->prop_list[$p]){      return $this->prop_list[$p];    }else{      return "该属性不存在!";    }  }  function __isset($prop){  //__isset()是自定义的方法, isset()是系统函数    $re = isset($this->prop_list[$prop]);    return $re;  }}$a1 = new A();$a1->p1 = 1;//不存在的属性名赋值,此时会调用_set(),并传过去"p1"和1$a1->p2 = 2;$a1->ac = 'avc';echo "
输出这些“不存在的属性”的值";echo "
a1->p1:" . $a1->p1;//不存在的属性名取值,此时会调用_get(),并传过去"p1"echo "
a1->p2:" . $a1->p2;echo "
a1->ac:" . $a1->ac;//下面演示isset判断不存在的属性$v1 = isset($a1->p1); //存在$v2 = isset($a1->ppp1); //不存在var_dump($v1);echo "
";var_dump($v2);?>

运行结果:

输出这些“不存在的属性”的值
a1->p1:1
a1->p2:2
a1->ac:avc
boolean true
boolean false

__UNSET($属性名)

当对一个对象不存在的属性进行unset()销毁时,就会自动调用内部方法:unset();

prop_list[$p] = $v;  }  function __get($p){    if($this->prop_list[$p]){      return $this->prop_list[$p];    }else{      return "该属性不存在!";    }  }  function __unset($prop){    unset($this->prop_list[$prop]);  }}$a1 = new A();$a1->p1 = 1;//不存在的属性名赋值,此时会调用_set(),并传过去"p1"和1echo "
a1->p1:" . $a1->p1;//不存在的属性名取值,此时会调用_get(),并传过去"p1"//下面演示unset销毁一个不存在的属性unset($a1->p1);echo "
a1->p1:" . $a1->p1;?>

运行结果为:

a1->p1:1
a1->p1:该属性不存在!

下面的例子中,声明一个Person类,并将所有的成员属性设置成private的。在类中添加自定义的“__isset()”和“__unset()”两个方法。在类外部使用“isset()”和“unset()”函数时,会自动调用这两个方法。代码如下:

name = $name;    $this->sex = $sex;    $this->age = $age;  }  private function __isset($propertyName){  //需要一个参数,是测定的私有属性的名称    if($propertyName == 'name'){      return false;  //返回假,不允许在类外部测定name属性    }    return isset($this->$propertyName);  //这里propertyName要加$符,因为这是参数,不是属性  }  private function __unset($propertyName){    if($propertyName == 'name')      return; //退出方法,不允许删除对象中的name属性    unset($this->$propertyName); //这里propertyName要加$符  }  public function say(){    echo "名字:" . $this->name . ",性别:" . $this->sex . ",年龄:" . $this->age . "
"; }}$person = new Person("yeoman", "男", 23);var_dump(isset($person->name)); //输出bool(false),不允许测定name属性var_dump(isset($person->sex)); //输出bool(true),存在sex私有属性var_dump(isset($person->age)); //输出bool(true),存在age私有属性var_dump(isset($person->id)); //输出bool(false),测定对象中不存在id属性unset($person->name); //删除私有属性name,但在 __unset()中不允许删除unset($person->sex); //删除对象中的私有属性sex,删除成功unset($person->age);$person->say(); //对象中的sex和age属性被删除,输出:名字:yeoman,性别:,年龄:?>

运行结果:

boolean false
boolean true
boolean true
boolean false
名字:yeoman,性别:,年龄:

方法重载

当对一个对象不存在的实例方法进行“调用”时,会自动调用类中的__call()这个魔术方法;

当对一个类不存在的静态方法进行“调用”时,会自动调用类中的__callstatic()这个魔术方法。

例子:直接调用不存在的方法

f1(); //不存在的方法?>

会报错,报错内容为:

Fatal error: Uncaught Error: Call to undefined method A::f1()

对上面报错作“优雅处理”:

f1(); //不存在的方法,但经过处理?>

运行结果为:

f1()方法不存在!

当对一个类不存在的静态方法进行“调用”时,会自动调用类中的__callstatic()这个魔术方法。和上面的处理类似。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

您可能感兴趣的文章:

  • php面向对象的方法重载两种版本比较
  • php继承中方法重载(覆盖)的应用场合
  • PHP使用方法重载实现动态创建属性的get和set方法
  • PHP利用func_get_args和func_num_args函数实现函数重载实例
  • php中拷贝构造函数、赋值运算符重载
  • PHP小技巧之函数重载
  • PHP实现重载的常用方法实例详解
  • PHP面相对象中的重载与重写
  • PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
  • php魔术函数__call()用法实例分析
  • PHP __call()方法实现委托示例
  • php 使用 __call实现重载功能示例


  • 上一条:
    PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
    下一条:
    PHP面向对象程序设计之构造方法和析构方法详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客