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数据库类
May 27 PHP
phpMyAdmin 安装配置方法和问题解决
Jun 08 PHP
apache+codeigniter 通过.htcaccess做动态二级域名解析
Jul 01 PHP
php实现12306余票查询、价格查询示例
Apr 17 PHP
浅析PHP的静态成员函数效率更高的原因
Jun 13 PHP
php5.3以后的版本连接sqlserver2000的方法
Jul 28 PHP
微信公众号开发之微信公共平台消息回复类实例
Nov 14 PHP
PHP 反射(Reflection)使用实例
May 12 PHP
Yii2 GridView实现列表页直接修改数据的方法
May 16 PHP
PHP赋值的内部是如何跑的详解
Jan 13 PHP
Laravel框架实现多数据库连接操作详解
Jul 12 PHP
如何用PHP websocket实现网页实时聊天
May 26 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打开文件fopen函数的使用说明
2013/07/05 PHP
完美解决在ThinkPHP控制器中命名空间的问题
2017/05/05 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
TP5框架实现上传多张图片的方法分析
2020/03/29 PHP
JS简单的轮播的图片滚动实例
2013/06/17 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
如何用jquery控制表格奇偶行及活动行颜色
2014/04/20 Javascript
浅谈Javascript数组索引
2015/07/29 Javascript
原生javascript+css3编写的3D魔方动画旋扭特效
2016/03/14 Javascript
获取jqGrid中选择的行的数据
2016/11/30 Javascript
javascript匿名函数中的'return function()'作用
2018/10/15 Javascript
react用Redux中央仓库实现一个todolist
2019/09/29 Javascript
详解React 条件渲染
2020/07/08 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
在Python中使用Neo4j数据库的教程
2015/04/16 Python
python实现字符串连接的三种方法及其效率、适用场景详解
2017/01/13 Python
你应该知道的python列表去重方法
2017/01/17 Python
详解Python多线程Selenium跨浏览器测试
2017/04/01 Python
详解Python开发中如何使用Hook技巧
2017/11/01 Python
Python中分支语句与循环语句实例详解
2018/09/13 Python
python re正则匹配网页中图片url地址的方法
2018/12/20 Python
PyCharm安装Markdown插件的两种方法
2019/06/24 Python
Kali Linux安装ipython2 和 ipython3的方法
2019/07/11 Python
python opencv将表格图片按照表格框线分割和识别
2019/10/30 Python
TensorFlow自定义损失函数来预测商品销售量
2020/02/05 Python
Python类super()及私有属性原理解析
2020/06/15 Python
经典c++面试题二
2015/08/14 面试题
实习护理工作自我评价
2013/09/25 职场文书
安全责任书模板
2014/07/22 职场文书
生产操作工岗位职责
2014/09/16 职场文书
某集团股份有限公司委托书样本
2014/09/24 职场文书
新员工试用期自我评价
2015/03/10 职场文书
会计简历自我评价
2015/03/10 职场文书
出生证明范本
2015/06/15 职场文书
家长对孩子的寒假评语
2015/10/09 职场文书
pandas中pd.groupby()的用法详解
2022/06/16 Python