浅谈多态以及php的实现方法
来源:互联网 发布:java log4j 中文乱码 编辑:程序博客网 时间:2024/06/05 08:21
先简单说一下多态
多态的三大特征:
- 子类继承父类
- 子类重写父类
- 父类指向子类
多态实现的前提:必须是类与类之间要有关系,要么继承,要么实现,存在重写(override),其实就是抽象函数或接口。
多态的应用:父类对象的引用指向子类对象,其实本质上就是一个向上转型。
举个模型例子,一家公司有员工类(Employee),还有其子类:销售(Sales)、市场(Market)、工程师(Engineer)等。某一天老板招待所有的员工开了个短会,完了之后对所有的员工(Employee)说,大家回去工作吧。在这里我们可以认为老板调用了所有员工对象的continueToWork()方法,而不是对一个个员工细说做什么工作,比如对销售部说你去制定销售计划(调用makeSalePlan();),对市场部说你去制定产品的价格(调用makeProductPrice();)….这种逐个细说的方式并不是面向对象,而是面向个体。可以确定的是,员工类应该有一个方法continueToWork()。而员工如何实现他们工作的方法却只有精确到子类才能确定,因为不同的员工的工作方式是不一样的。因此,我们很多时候只需要关心对象的父类型,而忽略更精确的子类型,比如上面老板叫大家回去工作时,他对全体员工说的,主要指的是全体员工类型。
上述的UML图:
多态的好处:大大提高程序的扩展,增强系统的灵活性,降低模块间的耦合。
具体Java代码实现如下:
abstract class Employee{ abstract void continueToWork();}class Sales extends Employee{ private void makeSalePlan(){ System.out.println("make sale plan"); } public void continueToWork(){ makeSalePlan(); }}class Market extends Employee{ private void makeProductPrice(){ System.out.println("make product price"); } public void continueToWork(){ makeProductPrice(); }}class Engineer extends Employee{ private void makeNewProduct(){ System.out.println("make new product"); } public void continueToWork(){ makeNewProduct(); }}
错误的调用示范:
class Demo{ public static void main(String[] args){ Sales s = new Sales(); s.continueToWork(); Market m = new Market(); m.continueToWork(); Engineer e = new Engineer(); e.continueToWork(); }}
以上的这种调用并不能称为多态,虽然看起来都通过调用continueToWork()来得到结果,但是并不是通过同一接口来实现的,这只是不同类的对象都有相同名称的接口方法,用上述模型来说,就是老板单独对销售部说你去工作,单独对市场部说你去工作,单独对工程师说你去工作,而不是对所有的员工说。
正确的调用方式:
class Demo{ public static void main(String[] args){ Work(new Sales());//Employee e = new Sales(); Work(new Market());//Employee e = new Market(); Work(new Engineer());//Employee e = new Engineer(); } public static void Work(Employee e){ e.continueToWork(); }}
上面通过调用统一的接口Work()来工作,这种调用才是多态。
还可以利用重载来实现伪多态:(注:本作者认为重载不属于多态的范畴,但是重载这种语言特性是可以帮助我们来实现伪多态的,具体请见本人的另一篇博文:《重载不应归在多态的范畴内》)
class Demo{ public static void main(String[] args){ Work(new Sales()); Work(new Market()); Work(new Engineer()); } public static void Work(Sales s){ s.continueToWork(); } public static void Work(Market m){ m.continueToWork(); } public static void Work(Engineer e){ e.continueToWork(); }}
为什么我称上面调用是伪多态呢?因为上述的这种方式,细究其实跟第一种错误调用方式是一样的,只不过利用了重载加以封装,使得看起来是通过统一的接口Work()来工作,但其实它并没有让父类对象的引用指向子类对象。
最后附上php代码实现多态:
<?phpabstract class Employee{ abstract function continueToWork();}class Sales extends Employee{ private function makeSalePlan(){ echo "make sale plan"; } public function continueToWork(){ $this->makeSalePlan(); }}class Market extends Employee{ private function makeProductPrice(){ echo "make product price"; } public function continueToWork(){ $this->makeProductPrice(); }}class Engineer extends Employee{ private function makeNewProduct(){ echo "make new product"; } public function continueToWork(){ $this->makeNewProduct(); }}class Demo{ public function Work($employeeObj){ $employeeObj->continueToWork(); }}//调用$obj = new Demo();$obj->Work(new Sales());$obj->Work(new Market());$obj->Work(new Engineer());?>
参考资料:
CSDN帖子:重载是不是多态?重载是不是面向对象?
Qi_Yuan的博文《java之多态的使用》
- 浅谈多态以及php的实现方法
- 浅谈PHP语音里的流程控制及实现方法
- 浅谈PHP的构造方法
- PHP变量的内存布局、实现方法以及作用域
- php生成短网址的思路以及实现方法
- PHP实现进程锁的方法以及详解
- 浅谈PHP+MYSQL身份验证的方法
- 【PHP】浅谈生成随机密码的方法
- Lua的类实现继承、多态以及setmetatable方法
- Lua的类实现继承、多态以及setmetatable方法
- Lua的类实现继承、多态以及setmetatable方法
- Lua的类实现继承、多态以及setmetatable方法
- Lua的类实现继承、多态以及setmetatable方法
- Lua的类实现继承、多态以及setmetatable方法
- 浅谈php国际(I18N)以及config包的使用
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- rtp,rtcp网络音视频写入(avi)文件,音视频同步方案
- spark 日志解析格式化
- c++作业四—项目3
- Windows下的php运行环境的部署
- vector的内存管理
- 浅谈多态以及php的实现方法
- 5-大数据分析之 druid 介绍
- Android 程序获取、设置铃声、音量、静音、扬声器
- GOPS 2017全球运维大会(北京站)亮点介绍
- Python基础入门(七)- 字符串
- 面向对象—this关键字
- 动态规划练习28:Maximum sum
- JavaEE四层模型
- nohup和screen命令---后台运行