PHP中实现函数重载
转载自:http://cnn237111.blog.51cto.com/2359144/1284085
由于PHP是弱类型语言,因此函数的输入参数类型无法确定(可以使用类型暗示,但是类型暗示无法用在诸如整型,字符串之类的标量类型上),并且对于一个函数,比如只定义了3个输入参数,PHP却运行调用的时候输入4个或者更多的参数。因此基于这2点,注定了PHP中无法重载函数,(类似Javascript语言),也无法有构造函数的重载。
由于实现函数的重载对提高开发效率很有帮助,如果能象C#或者C++那样,那就非常好了。事实上,PHP的提供了一个魔术方法,mixed __call ( string name, array arguments )。这个方法在php手册中也有提及,根据官方文档,称此方法可以实现函数重载。当调用对象中一个不存在的方法的时候,如果定义了__call()方法,则会调用该方法。比如下面的代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<?phpclass A{ function __call ( $name, $arguments ) { echo "__call调用<br/>"; echo '$name为'.$name."<br/>"; print_r ($arguments); }}(new A)->test("test","argument");?> |
运行结果为:
__call调用
$name为test
Array ( [0] => test [1] => argument )
因此只需要利用该魔术方法既可以实现函数重载。
代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<?phpclass A{ function __call ($name, $args ) { if($name=='f') { $i=count($args); if (method_exists($this,$f='f'.$i)) { call_user_func_array(array($this,$f),$args); } } } function f1($a1) { echo "1个参数".$a1."<br/>"; } function f2($a1,$a2) { echo "2个参数".$a1.",".$a2."<br/>"; } function f3($a1,$a2,$a3) { echo "3个参数".$a1.",".$a2.",".$a3."<br/>"; }}(new A)->f('a');(new A)->f('a','b');(new A)->f('a','b','c');?> |
输出如下:
1个参数a
2个参数a,b
3个参数a,b,c
同样的在PHP中,实现构造函数的重载,也只能变通的实现。实现的关键要素是获取输入参数,并且根据输入参数判断调用哪个方法。下面是一个示例代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?phpclass A{ function __construct() { echo "执行构造函数<br/>";$a = func_get_args(); //获取构造函数中的参数 $i = count($a); if (method_exists($this,$f='__construct'.$i)) {call_user_func_array(array($this,$f),$a); } } function __construct1($a1) { echo "1个参数".$a1."<br/>"; } function __construct2($a1,$a2) { echo "2个参数".$a1.",".$a2."<br/>"; }function __construct3($a1,$a2,$a3) { echo "3个参数".$a1.",".$a2.",".$a3."<br/>"; }}$o = new A('a');$o = new A('a','b');$o = new A('a','b','c');?> |
执行构造函数
1个参数a
执行构造函数
2个参数a,b
执行构造函数
3个参数a,b,c
顺便提一下,和c#等面向对象语言一样,php中,把构造函数设成私有或者protected,就不能实例化该对象了。
PHP中实现函数重载的更多相关文章
- C++解析(16):友元与类中的函数重载
0.目录 1.友元的尴尬能力 2.类中的函数重载 3.小结 1.友元的尴尬能力 什么是友元? 友元是C++中的一种关系 友元关系发生在函数与类之间或者类与类之间 友元关系是单项的,不能传递 友元的用法 ...
- 关于在C#中对函数重载理解
函数重载是个什么概念,才接触的这个概念的时候我也是完全昏了,还在自己看看了书后就理解了.那什么是函数重载呢?我个人理解的是在同一个作用域下有多个同名的函数,但是他们的形参的类型是不同的,或者参数个数是 ...
- 《挑战30天C++入门极限》新手入门:C++中的函数重载
新手入门:C++中的函数重载 函数重载是用来iostream> using namespace std; int test(int a,int b); float test(flo ...
- js中的函数重载
函数重载与js 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,也就是说用 ...
- c++中的函数重载、函数重写、函数重定义
目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...
- 4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)
本章主要内容: 1)函数重载 2)C++调用C代码 3)new/delete关键字实现动态内存分配 4)namespace命名空间 大家都知道,在生活中,动词和不同的名词搭配一起,意义都会大有不同,比 ...
- c++程序设计中的函数重载
函数重载的意思是在一个作用域内(命名空间内)定义了某个或某些具有相同名称的函数,但是他们的参数列表和定义(实现)不相同,如果相同的话,就没啥意义了.当调用一个重载函数时,编译器会通过所使用的参数类型. ...
- C++类中的函数重载
1,本课程最初阶段就学习了函数重载,但是那时研究目标仅限于全局函数,到目前 为止我们学习了三种函数: 1,全局函数: 2,普通成员函数: 3,静态成员函数: 这三种不同类型的函数之间是否可以构成重载, ...
- 从两个角度理解为什么 JS 中没有函数重载
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空 ...
随机推荐
- PostgreSQL CPU满(100%)性能分析及优化(转)
PostgreSQL CPU满(100%)性能分析及优化 转自:https://help.aliyun.com/knowledge_detail/43562.html 在数据库运维当中,一个DB ...
- .NET中,在方法参数的类型前加一个OUT是做什么用的
话说古时候,在一个名字叫C#的繁华的大城市里面,有两家珠宝加工店,一家叫ref,另外一家叫out. 有一天,有名字叫a和b的两个人每人都各带了一公斤黄金要加工首饰. a去了ref店,ref的掌柜告诉a ...
- 微信小程序自定义tabbar的问题
个人感觉小程序的tab样式自定义的能力有所欠缺,不够美观,于是今天自己diy了一个tab 测试的时候发现,无论是使用navigator跳转(会出现点击的效果)还是用bindtap(触摸),因为没有定义 ...
- ICE:slice语言常识整理
ICE:Slice语言(二)--源文件和词法规则: 文件命名 Slice的源文件以.ice为扩展名. 对于大小写不区分的系统(例如DOS),文件的扩展名可以大写,也可以小写,例如Cli ...
- .pyc和.pyo文件有何用
百度知道:http://zhidao.baidu.com/link?url=_tFP1xglFnoEBObWtIArI3b3Ft0PQowx5m5ruIaX3mFIAFVr7vX45Lfb0geCjA ...
- Android学习笔记之Toast详解
1. 贴一段Android API-Toast Toast public class Toast extends Object java.lang.Object ↳ android.widget.T ...
- [转]Java 8新特性探究(lambda)
原文地址:http://my.oschina.net/benhaile/blog/175012 目录[-] 函数式接口 Lambda语法 方法引用 总结 函数式接口 函数式接口(functional ...
- 一个关于PCA的疑问
我们知道PCA干的事情是把n维的样本投影到k维,同时丢失的信息能够达到最少. 为什么说principal component是covariance matrix的特征值中最大的前k个对应的特征向量上的 ...
- 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包
MSBuild 的 Task 为我们扩展项目的编译过程提供了强大的扩展性,它使得我们可以用 C# 语言编写扩展:利用这种扩展性,我们可以为我们的项目定制一部分的编译细节.NuGet 为我们提供了一种自 ...
- vue-router教程二(要素篇之新手入门)
注意,我们将在指南中使用es 2015代码样本.此外,所有示例都将使用VUE的完整版本来使在线模板编译成为可能.请参阅这里的更多细节. 用vue路由器创建单页应用程序是非常简单的.使用vue.js,我 ...