PHP的方法重载实现
PHP提出面向对象以来,就有着各种各样的问题,其中,不直接支持对象方法重载就是一个让人纠心的问题,在其他语言里面,大可以有以下写法(以下是C++写法):
class Abc(){
public function a( int x){
cout<<x<<endl;
}
public function a( int x , int y){
cout<<x<<endl;
cout<<y<<endl;
}
} Abc aa = new Abc();
aa.a();//
aa.a(,)//1 2
这些方法,在某些时候是非常有用的。可是,在PHP里面如果 你直接在一个类里面定义两个函数名一样的函数(即使他们的参数个数不一样),是会报错的。
所以对于PHP我们要实现方法重载就只能另辟他径了,下面我给出两种方式:
一、利用__call函数
在 PHP 中的方法调用是这样工作的。首先,PHP 解释器在类上查找方法。如果方法存在,PHP 就调用它。如果没有,那么就调用类上的魔术函数 __call(如果这个方法存在的话)。如果 __call 失败,就调用父类方法,依此类推。看下面的例子:
class OverloadTest{
public function __call($name,$para){
if($name=='construct'){
switch (count($para)){
case 0:
$this->cons1();
break;
case 1:
$this->cons2($para[0]);
break;
default:
print "wrong para";
}
}else{
print 'Undefined method '.$name;
}
}
function cons1(){
echo "cons1() called";
}
function cons2($var){
echo "cons2() called.";
}
}
$foo = new OverloadTest();
$foo->construct();
$foo->construct('test');
二、使用func_get_args()和func_num_args()函数获取参数个数
这两个函数分别是获取函数的参数列表及参数长度。根据参数长度,我们可以有跟上面一样的做法,但是这个方法看起来更和谐点。看下面的例子:
class OverloadTest{
public function __construct{
$args = func_get_args();
switch (func_num_args()){
case 0:
$this->_cons1();
break;
case 1:
$this->_cons2($args[0]);
break;
default:
print "wrong para";
}
}
private function _cons1(){
echo "cons1() called";
}
private function _cons2($var){
echo "cons2() called.";
}
}
$foo = new OverloadTest();
$foo->construct();
$foo->construct('test');
两种方式都算是比较容易的实现了函数重载,但是这种模拟的做法也只是临时之计,希望PHP在未来面象对象的实现能够更全面一些。
PHP的方法重载实现的更多相关文章
- java方法重载(overload)、重写(override);this、super关键简介
一.方法重载: 条件:必须在一个类中,方法名称相同,参数列表不同(包括:数据类型.顺序.个数),典型案例构 造方重载. 注意:与返回值无关 二.方法重写: 条件: (1)继承某个类或实现某接口 (2 ...
- Java之方法重载篇(我重载了,你要如何来调用我。。)
一.课前引言 请看一下代码,你发现什么特殊之处了吗? public class MethodOverload { public static void main(String[] args) { ...
- 【java开发】方法重写和方法重载概述
类的继承 父类-子类 关键字 extends 新建一个父类 public class Person { private String name; private int ...
- 方法构造和方法重载之奥特曼与大boss之战
知识点的总结: 1.类中的方法分为两类:1.普通方法: 2.构造方法. 2.构造方法的格式: public 类名(数据类型 参数名,...){ } 3.构造方法的用途: 1.实例化对象. 2. ...
- JavaScript中的方法重载
对js有些了解的人都知道,在js中根本就不存在像C#中的那种方法重载,而有的只是方法的覆盖,当你在js中敲入两个或多个同名的方法的时候,不管方法(函数)的参数个数怎么个不同,这个方法名只能属于最后定义 ...
- PHP面向对象编程——深入理解方法重载与方法覆盖(多态)
什么是多态? 多态(Polymorphism)按字面的意思就是“多种状态”.在面向对象语言中,接口的多种不同的实现方式即为多态.引用Charlie Calverts对多态的描述——多态性是允许你将父对 ...
- c#方法重载,可选参数,命名参数。
其实这里没什么可说哦,c++的语法大同小异.先看一段代码. class Program { public static void Test(int a) { Console.WriteLine(&qu ...
- WCF实现方法重载
一.服务契约(包括回调契约)通过指定不同的OperationContract.Name来实现重载方法,当然代码部份还是必需符合C#的重载要求,即相同方法名称,不同的参数个数或参数类型 namespac ...
- java中的方法重载与重写以及方法修饰符
1. 方法重载Overloading , 是在一个类中,有多个方法,这些方法的名字相同,但是具有不同的参数列表,和返回值 重载的时候,方法名要一样,但是参数类型和参数个数不一样,返回值类型可以相同,也 ...
- 方法重写和方法重载;this关键字和super关键字
1:方法重写和方法重载的区别?方法重载能改变返回值类型吗? 方法重写: 在子类中,出现和父类中一模一样的方法声明的现象. 方法重载: 同一个类中,出现的方法名相同,参数列表不同的现象. 方法重载能改变 ...
随机推荐
- vue的data用到this问题
问题:在vue中用vue-awesome-swiper,在data中初始化,用到swiper一个方法onTap,然后再调vue的一个函数,用到this,可是... data() { return { ...
- window下线程同步之(原子锁)
原子锁:当多个线程同时对同一资源进行操作时,由于线程间资源的抢占,会导致操作的结果丢失或者不是我们预期的结果. 比如:线程A对一个变量进行var++操作,线程B也执行var++操作,当线程A执行var ...
- JS获取 KindEditor textarea 标签 html内容失败的解决方法。
KindEditor 这个 东西 研究的不多,JS在通过调用getElementById 获取文本id的内容时候,KindEditor 尚未将内容同步,官方给的解决方法是afterBlur: func ...
- java程序中如何为一个while(true)循环计时,超过一定时间比如10个小时就退出循环?
public void execute(int hour){ long t1 = System.currentTimeMillis(); while(true){ long t2 = System.c ...
- jquery键盘常见事件
一.在看jquery的时候有几个常见的键盘事件,我写在这里: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() keyup事件会在按键释放时触发,也就是你按下键盘起来 ...
- 使用jsonp形式跨域访问实现电商平台的左侧导航栏
电商平台有个具备的左侧商品类目的导航栏的结构. 通过jsonp跨域访问电商平台的后台管理系统商品分类.(主要实现后台Java代码) 实现基本步骤: 1.在后台管理系统中准备相应的json数据. poj ...
- 洛谷P2236 HNOI2002 彩票 [暴搜]
题目传送门 彩票 分析: 虽然题目标签上标的是Splay,但我一个蒟蒻至今也沒掌握平衡树,所以就索性一个暴搜,加一点剪枝就水过去了- 代码: #include<cstdio> #inclu ...
- Java九大内置对象
Java九大内置对象 内置对象/作用域(每一种作用域的生命周期是不一样的): 1, application 全局作用域 2, session 会话作用域 ...
- 携带结果的任务 Callable 与 Future
Executor框架使用Runnable作为其基本任务表示形式.Runnable是一种有很大局限的抽象,它不能返回一个值或者抛出一个受检查的异常. 但是许多任务实际上都是存在延迟的计算,比如执行数据库 ...
- Tyvj1933绿豆蛙的归宿
给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达终点.绿豆蛙从起点出发,走向终点. 到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以 ...