php面向对象的方法重载两种版本比较


Posted in PHP onSeptember 08, 2008

多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。

PHP4 中仅仅实现了面向对象的部分的、简单的功能,而 PHP5 以后对对象的支持就强大的多了。

对于多态的实现,PHP4 只支持覆盖(override),而不支持重载(overload)。但我们可以通过一些技巧来“模拟”重载的实现。

PHP5 虽然可以支持覆盖和重载,但重载在具体实现上,和其他语言还有较大的差别。

1,在 PHP4 中“模拟”重载

试看以下代码:

<?php
//根据参数个数选择执行不同的方法(在 PHP4 中模拟"重载"(多态的一种)

class Myclass
{
function Myclass()
{
$method = "method" . func_num_args();
$this->$method();
}

function method1($x)
{
echo "method1";
}

function method2($x, $y)
{
echo 'method2';
}
}

//通过在类中的额外的处理,使用这个类对用户是透明的:
$obj1 = new Myclass('A'); //将调用 method1
$obj2 = new Myclass('B','C'); //将调用 method2
?>

以上代码中,通过在构造函数中使用 func_num_args() 函数取到参数的个数,自动执行 method1 或 method2 方法。我们可以结合函数 func_get_arg(i) 和 func_get_args() 对以上示例进行改进。

2,在 PHP5 中使用重载

先看以下示例:

<?php 
class Myclass 
{ 
public $attriable; 
public $one = "this is one"; 
public $two = "this is two"; function __construct() 
{ 
} 
function one($one) 
{ 
$this->one=$one; 
$this->attriable = $this->one; 
} 
function one($one, $two) 
{ 
$this->one=$one; 
$this->two=$two; 
$this->attriable = $this->one . $this->two; 
} 
function display() 
{ 
echo $this->attriable; 
} 
} 
$one = "this is my class"; 
$two = "Im the best"; 
$myclass = new myclass(); 
$myclass->one($one); 
$myclass->display(); 
$myclass->one($one, $two); 
$myclass->display(); 
//本例的做法,在 PHP 中是不正确的! 
?>

使用过 C++、Java、C# 重载的人,很习惯地就会写出以上的重载实现的 PHP 代码。但这在 PHP5 中是不正确的。PHP5 并不是对前述几种语言的模仿,而是有自己的一套实现方法重载的方法(是好是坏,这里不讨论)。 虽说 PHP5 的类较 PHP4 强大了许多,但是在“重载”这个问题上并没有像我们预期的那样“改善”。在“强”类型的语言中可以通过不同的参数类型来实现“重载”,比如C++、Java、C# 等。在“固定参数”传递的语言中,还可以通过参数的个数进行传递,比如 Java,但是 PHP 是弱类型语言,因此不会出现类似以上的“重载”。

PHP5 中重载可以通过 __get, __set, and __call 几个特殊方法来进行。当 Zend 引擎试图访问一个成员并没有找到时,PHP将会调用这些方法。

在以下示例中,__get和__set代替所有对属性变量数组的访问。如果必要,你还可以实现任何类型你想要的过滤。例如,脚本可以禁止设置属性值, 在开始时用一定的前缀或包含一定类型的值。__call 方法说明了你如何调用未经定义的方法。你调用未定义方法时,方法名和方法接收的参数将会传给__call方法, PHP传递__call的值返回给未定义的方法。

<?php 
class Overloader 
{ 
private $properties = array(); function __get($property_name) 
{ 
if(isset($this->properties[$property_name])) 
{ 
return($this->properties[$property_name]); 
} 
else 
{ 
return(NULL); 
} 
} 
function __set($property_name, $value) 
{ 
$this->properties[$property_name] = $value; 
} 
public function __call($method, $p) 
{ 
print("Invoking $method()<br>\n"); 
//print("Arguments: "); 
//print_r($args); 
if($method == 'display') 
{ 
if(is_object($p[0])) 
$this->displayObject($p[0]); 
else 
if(is_array($p[0])) 
$this->displayArray($p[0]); 
else 
$this->displayScalar($p[0]); 
} 
} 
public function displayObject($p) 
{ 
echo ("你传入的是个对象,内容如下:<br>"); 
print_r($p); 
echo "<hr>"; 
} 
public function displayArray($p) 
{ 
echo ("你传入的是个数组,内容如下:<br>"); 
print_r($p); 
echo "<hr>"; 
} 
public function displayScalar($p) 
{ 
echo ("你传入的是个单独变量,内容如下:<br>" . $p); 
echo "<hr>"; 
} 
} 
$o = new Overloader(); 
//调用 __set() 给一个不存在的属性变量赋值 
$o->dynaProp = "Dynamic Content"; 
//调用 __get() 
print($o->dynaProp . "<br>\n"); 
//调用 __call() 
//$o->dynaMethod("Leon", "Zeev"); 
$o->display(array(1,2,3)); 
$o->display('Cat'); 
?>

以上代码中,调用了 display() 方法,可以根据参数的类型和个数调用类中的对应的代码段,从而实现了对象方法的重载。

PHP 相关文章推荐
随时给自己贴的图片加文字的php代码
Mar 08 PHP
深入理解PHP之数组(遍历顺序)  Laruence原创
Jun 13 PHP
用Json实现PHP与JavaScript间数据交换的方法详解
Jun 20 PHP
php导入导出excel实例
Oct 25 PHP
PHP实现股票趋势图和柱形图
Feb 07 PHP
php带抄送和密件抄送的邮件发送方法
Mar 20 PHP
PHP版QQ互联OAuth示例代码分享
Jul 05 PHP
PHP实现linux命令tail -f
Feb 22 PHP
php生成验证码,缩略图及水印图的类分享
Apr 07 PHP
thinkPHP js文件中U方法不被解析问题的解决方法
Dec 05 PHP
ThinkPHP5 验证器的具体使用
May 31 PHP
php 原生分页
Apr 01 PHP
php+AJAX传送中文会导致乱码的问题的解决方法
Sep 08 #PHP
php chr() ord()中文截取乱码问题解决方法
Sep 08 #PHP
wiki-shan写的php在线加密的解密程序
Sep 07 #PHP
php单件模式结合命令链模式使用说明
Sep 07 #PHP
网友原创的PHP模板类代码
Sep 07 #PHP
php 特殊字符处理函数
Sep 05 #PHP
php include,include_once,require,require_once
Sep 05 #PHP
You might like
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
ASP.NET jQuery 实例14 在ASP.NET form中校验时间范围
2012/02/03 Javascript
jQuery-onload让第一次页面加载时图片是淡入方式显示
2012/05/23 Javascript
jquery实现marquee效果(文字或者图片的水平垂直滚动)
2013/01/07 Javascript
JS与C#编码解码
2013/12/03 Javascript
js鼠标悬浮出现遮罩层的方法
2015/01/28 Javascript
js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
2015/11/09 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
2016/06/12 Javascript
基于Layer+jQuery的自定义弹框
2020/05/26 Javascript
使用JavaScript解决网页图片拉伸问题(推荐)
2016/11/25 Javascript
JavaScript结合HTML DOM实现联动菜单
2017/04/05 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
sublime text配置node.js调试(图文教程)
2017/11/23 Javascript
vue init webpack myproject构建项目 ip不能访问的解决方法
2018/03/20 Javascript
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
2018/07/30 Javascript
通过vue-cli3构建一个SSR应用程序的方法
2018/09/13 Javascript
[02:51]DOTA2 2015国际邀请赛中国区预选赛第一日战报
2015/05/27 DOTA
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
[49:08]Secret vs VP 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python搭建HTTP服务器和FTP服务器
2017/03/09 Python
在Python的一段程序中如何使用多次事件循环详解
2017/09/07 Python
浅谈Pandas中map, applymap and apply的区别
2018/04/10 Python
实践Vim配置python开发环境
2018/07/02 Python
django 扩展user用户字段inlines方式
2020/03/30 Python
在python里使用await关键字来等另外一个协程的实例
2020/05/04 Python
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
英国游戏机和游戏购物网站:365games.co.uk
2018/06/18 全球购物
个人素质的自我评价分享
2013/12/16 职场文书
西式婚礼证婚词
2014/01/12 职场文书
24岁生日感言
2014/01/13 职场文书
春季防火方案
2014/05/10 职场文书
2014年车间工作总结
2014/11/21 职场文书
幼儿园小朋友毕业感言
2015/07/30 职场文书
Pygame Time时间控制的具体使用详解
2021/11/17 Python
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL