PHP面向对象编程之深入理解方法
文章主要介绍了PHP面向对象编程之深入理解方法重载与方法覆盖(多态)的相关资料,需要的朋友可以参考下
什么是多态?
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针(没错这段话来自百度百科)。那么多态的作用是什么,它有什么实际开发价值呢?在实际的应用开发中,采用面向对象中的多态主要在于可以将不同的子类对象都当作一个父类来处理,并且可以屏蔽不同子类对象之间所存在的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
下面就是PHP中多态的两个实现
方法重载(overload)
重载是类的多态的一种实现。函数重载指一个标识符被用作多个函数名,且能够通过函数的参数个数或参数类型将这些同名的函数区分开来,调用不发生混淆。即当调用的时候,虽然方法名字相同,但根据参数的不同可以自动调用相应的函数。
class A{
public function test(){
echo "test1";
}
public function test($a){
echo "test2";
}
}
$a=new A();
$a->test();
$a->test($a);
假如php直接支持方法重载的话。那么上面的例子执行后传参和不传参就会返回不同的.值。然而php并不直接支持重载,这就意味着你如果直接按上面这样定义的话,就会报错的。会报什么错呢?会报如下的错误。
这意思就是不能重复定义A函数,报错的行数也正是下面这行。
public function test($a){
所以说php是并不直接支持重载的。合着说了这么半天php并不支持。。别急,我说的是并不直接支持,所以说是我们可以让php间接支持。这时候就要用到一个函数来支持重载了。就是__call()。__call()方法必须带有两个参数。第一个包含了被调用的方法名称,而第二个参数包含了传递给该方法的参数数组。可以通过这个方法实现类似于函数重载的功能。看下面的代码。
public function __call($method,$p)
{
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]);
}
}
}
//下面是对上面定义的调用
$ov=new overload;
$ov->display(array(1,2,3));
$ov->display('cat');
定义方法的时候,可以看到有三个分支,如果一个对象传递给display()方法,就调用的是displayObject()方法;如果传递的是一个数组,调用displayArray();传递的是其他的内容的话,则调用的是displayScalar()方法。。。可以看到下面调用时,第一个是传递了一个数组,则调用displayArray()。第二个传入的不是对象也不是数组,则属于其他内容,调用的是displayScalar()方法。所以这样子就用__call()方法实现了类似于其他语言的方法重载。
方法覆盖(override)
所谓覆盖,从本质上来说就是重写。就是当子类继承父类的一些方法后,子类又在其内部定义了相同的方法,则这个新定义的方法会覆盖继承而来的父类的方法,子类只能调用其内部定义的方法。
有以下几点要求:
1.当一个父类和子类有一个方法,参数和名字完全一致,那么子类方法会覆盖父类的方法。
2.在实行方法覆盖的时候,访问修饰符可以是不一样的,但是子类的访问范围必须大于等于父类的访问范围。
3.要求参数和名字一样。并不是要求子类,父类名称相同。
下面是对这几点的解释:
第一点,必须参数一致,才会实现方法覆盖。当参数个数不一致,则会报错(这就牵扯到上面说所得方法重载)。当方法名字不一致,就不会覆盖,只是子类新定义的方法。;
第二点,这是php这些语言设计时的规定吧。我是这么理解的是访问高一层的东西比较容易,如果再去访问底层的东西权限肯定要高一些。
看代码:
class people{
protected function sing(){
echo "人唱歌";
}
}
class woman extends people{
public function sing(){
echo "女人唱歌";
}
}
$woman1=new woman();
$woman1->sing();
-
如何在php与js中分别获取客户度mac地址
导语:如何在php与js中分别获取客户度mac地址的呢?学代码的你懂吗?下面的是本站小编为大家搜集的`相关资料,供大家参考。代码如下:<?phpclassMacAddr{public$returnArray=array();public$macAddr;function__contruct($os_type=null){if(is_null($os_type))$os_type=...
-
php内核分析之opcode
在做PHP项目之前首先要对所运用的知识了解,下面是本站小编精心为大家整理的php内核分析之opcode,希望对有需要的人有帮助,更多内容请关注应届毕业生网!这里阅读的php版本为PHP-7.1.0RC3,阅读代码的平台为linux查看opcodephp是先把源码解析成opcode,然后再把opcode传...
-
php中zend相对路径问题
php下使用zend相对路径的处理方法。如何使用呢?就跟随本站小编一起去了解下吧,想了解更多相关信息请持续关注我们应届毕业生考试网!<?phpdefine('P_S',PATH_SEPARATOR);define('ROOT',"../");set_include_path(ROOT.P_S.'Zend'.P_S_incl...
-
PHP中超全局变量$GLOBALS和global的区别
人之所以能,是相信能。努力总是会有收获的。下面是小编整理的PHP中超全局变量$GLOBALS和global的区别,希望对大家有用,更多消息请关注应届毕业生网。一、超全局变量$GLOBALSPHP超全局变量有很多,如下的都属于超全局变量(Superglobal):$GLOBALS,$_SERVER,$_GET,$_POST,$_...