深入php多态的实现详解


Posted in PHP onJune 09, 2013

多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息将可以产生不同的结果,这种现象称为多态性。

多态性允许每个对象以适合自身的方式去响应共同的消息。多态性增强了软件的灵活性和重用性。

在面向对象的软件开发中,多态性是最为重要的部分之一。面向对象编程并不只是将相关的方法与数据简单的结合起来,而是采用面向对象编程中的各种要素将现实生活中的各种情况清晰的描述出来。这一小节将对面向对象编程中的多态性作详细的讲解。

1.什么是多态
 
多 态(Polymorphism)按字面上意思理解就是“多种形状”。可以理解为多种表现形式,也即“一个对外接口,多个内部实现方法”。在面向对象的理论 中,多态性的一般定义为:同一个操作作用于不同的类的实例,将产生不同的执行结果。也即不同类的对象收到相同的消息时,将得到不同的结果。

在实际的应用开发中,采用面向对象中的多态主要在于可以将不同的子类对象都当作一个父类来处理,并且可以屏蔽不同子类对象之间所存在的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

2.多态的应用设计
 
在实际的应用开发中,通常为了使项目能够在以后的时间里的轻松实现扩展与升级,需要通过继承实现可复用模块进行轻松升级。在进行可复用模块设计时,就需要尽可能的减少使用流程控制语句。此时就可以采用多态实现该类设计。

【示例】例举了通常采用流程控制语句实现不同类的处理。其代码如下所示。

<?php
    class painter{                                    //定义油漆工类
        public function paintbrush(){                 //定义油漆工动作
            echo "油漆工正在刷漆!/n";
        }
    }
    class typist{                                    //定义打字员类
        public function typed(){                     //定义打字员工作
            echo "打字员正在打字!/n";
        }
    }
    function printworking($obj){                    //定义处理类
        if($obj instanceof painter){                //若对象是油漆工类,则显示油漆工动作
            $obj->paintbrush();
        }elseif($obj instanceof typist){            //若对象是打字员类,则显示打字员动作
            $obj->typed();
        }else{                                    //若非以上类,则显示出错信息
            echo "Error: 对象错误!";
        }
    }
    printworking(new painter());                    //显示员工工作
    printworking(new typist());                     //显示员工工作
?>

分析:在上述程序中,首先定义两个员工类:油漆工类和打字员类。然后定义一个处理函数,在该函数中,判断员工是否为已经定义的员工,打印出员工的工作状态。其结果如下所示。
油漆工正在刷漆 
打字员正在打字
从 以上程序可轻松看出,若想显示其几种员工的工作状态,需要首先定义该员工类,并在该员工类中定义员工的工作,然后在printworking()函数中增 加elseif语句以检查对象是哪一员工类的实例。这在实际的应用中,是非常不可取的。若此时采用多态,则可以轻松解决此问题。

可以首先创建一个员工父类,所有的员工类将继承自该员工父类,并且继承父类的所有方法与属性。然后在员工类中创建“是一”关系,判断是否为合法的员工。

【示例】例举了采用多态的方式改写上例。其代码如下所示。

<?php
class employee{//定义员工父类
protected function working(){//定义员工工作,需要在子类的实现
echo "本方法需要在子类中重载!";
}
}
class painter extends employee{//定义油漆工类
public function working(){//实现继承的工作方法
echo "油漆工正在刷漆!/n";
}
}
class typist extends employee{//定义打字员类
public function working(){
echo "打字员正在打字!/n";
}
}
class manager extends employee{//定义经理类
public function working(){
echo "经理正在开会!";
}
}
function printworking($obj){//定义处理方法
if($obj instanceof employee){//若是员工对象,则显示其工作状态
$obj->working();
}else{//否则显示错误信息
echo "Error: 对象错误!";
}
}
printworking(new painter());//显示油漆工的工作
printworking(new typist());//显示打字员的工作
printworking(new manager());//显示经理的工作
?>

分析:在上述程序中,首先定义一个员工基类,并定义一个员工工作状态的方法。然后定义将继承自员工基类的三个员工类:油漆工类、打字员类和经理类。然后定义显示员工工作状态的方法。并在该方法中创建一个“是一”关系,用于判断是否为合法的员工。其结果如下所示。
油漆工正在刷漆!
打字员正在打字!
经理正在开会!
从上例可发现,无论增加多少个员工类,只需要实现自员工父类继承的该员工类和方法。而无须修改显示员工工作状态的方法printworking()。  
PHP 相关文章推荐
AJAX for PHP简单表数据查询实例
Jan 02 PHP
PHP 魔术函数使用说明
May 14 PHP
php unset全局变量运用问题的深入解析
Jun 17 PHP
用 Composer构建自己的 PHP 框架之基础准备
Oct 30 PHP
PHP将session信息存储到数据库的类实例
Mar 04 PHP
php操作(删除,提取,增加)zip文件方法详解
Mar 12 PHP
PHP中的traits简单使用实例
May 13 PHP
深入理解PHP之OpCode原理详解
Jun 01 PHP
Laravel学习教程之IOC容器的介绍与用例
Aug 15 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
Nov 14 PHP
Ubuntu上安装yaf扩展的方法
Jan 29 PHP
PHP7内核CGI与FastCGI详解
Apr 14 PHP
深入PHP autoload机制的详解
Jun 09 #PHP
定义php常量的详解
Jun 09 #PHP
基于php冒泡排序算法的深入理解
Jun 09 #PHP
深入apache host的配置详解
Jun 09 #PHP
探讨如何在PHP开启gzip页面压缩实例
Jun 09 #PHP
基于PHP CURL用法的深入分析
Jun 09 #PHP
探讨PHP使用eAccelerator的API开发详解
Jun 09 #PHP
You might like
封装ThinkPHP的一个文件上传方法实例
2014/10/31 PHP
php自定文件保存session的方法
2014/12/10 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
PHP云打印类完整示例
2016/10/15 PHP
PHP设置Cookie的HTTPONLY属性方法
2017/02/09 PHP
setTimeout 不断吐食CPU的问题分析
2009/04/01 Javascript
JQuery 操作Javascript对象和数组的工具函数小结
2010/01/22 Javascript
JQuery对checkbox操作 (循环获取)
2011/05/20 Javascript
javascript实现状态栏中文字动态显示的方法
2015/10/20 Javascript
Bootstrap每天必学之导航
2015/11/26 Javascript
jQuery EasyUI菜单与按钮详解
2016/07/13 Javascript
AngularJS基础 ng-src 指令简单示例
2016/08/03 Javascript
js实现对table的增加行和删除行的操作方法
2016/10/13 Javascript
JS实现动画兼容性的transition和transform实例分析
2016/12/13 Javascript
js实现3D图片环展示效果
2017/03/09 Javascript
js实现加载页面就自动触发超链接的示例
2017/08/31 Javascript
完美解决linux下node.js全局模块找不到的情况
2018/05/16 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
2018/09/12 Javascript
vue基于element-ui的三级CheckBox复选框功能的实现代码
2018/10/15 Javascript
JavaScript中遍历的十种方法总结
2020/12/15 Javascript
[01:01:29]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第一场
2018/04/05 DOTA
[01:01:01]完美世界DOTA2联赛循环赛 GXR vs FTD BO2第一场 10.29
2020/10/29 DOTA
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
2017/09/08 Python
flask入门之文件上传与邮件发送示例
2018/07/18 Python
python使用Paramiko模块实现远程文件拷贝
2019/04/30 Python
keras实现多GPU或指定GPU的使用介绍
2020/06/17 Python
Python Switch Case三种实现方法代码实例
2020/06/18 Python
小程序瀑布流解决左右两边高度差距过大的问题
2019/02/20 HTML / CSS
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
中医学专业自荐信范文
2014/04/01 职场文书
年度优秀员工获奖感言
2014/08/15 职场文书
大学生个人学习总结
2015/02/15 职场文书
2015年体育教师个人工作总结
2015/05/12 职场文书
MySQL系列之二 多实例配置
2021/07/02 MySQL
浅析JavaScript中的变量提升
2022/06/01 Javascript