浅谈多态以及php的实现方法
2018-02-24 15:52
411 查看
先简单说一下多态
多态的三大特征:子类继承父类
子类重写父类
父类指向子类
多态实现的前提:必须是类与类之间要有关系,要么继承,要么实现,存在重写(override),其实就是抽象函数或接口。
多态的应用:父类对象的引用指向子类对象,其实本质上就是一个向上转型。
举个模型例子,一家公司有员工类(Employee),还有其子类:销售(Sales)、市场(Market)、工程师(Engineer)等。某一天老板招待所有的员工开了个短会,完了之后对所有的员工(Employee)说,大家回去工作吧。在这里我们可以认为老板调用了所有员工对象的continueToWork()方法,而不是对一个个员工细说做什么工作,比如对销售部说你去制定销售计划(调用makeSalePlan();),对市场部说你去制定产品的价格(调用makeProductPrice();)….这种逐个细说的方式并不是面向对象,而是面向个体。可以确定的是,员工类应该有一个方法continueToWork()。而员工如何实现他们工作的方法却只有精确到子类才能确定,因为不同的员工的工作方式是不一样的。因此,我们很多时候只需要关心对象的父类型,而忽略更精确的子类型,比如上面老板叫大家回去工作时,他对全体员工说的,主要指的是全体员工类型。
上述的UML图:
多态的好处:大大提高程序的扩展,增强系统的灵活性,降低模块间的耦合。
具体Java代码实现如下:
多态的三大特征:子类继承父类
子类重写父类
父类指向子类
多态实现的前提:必须是类与类之间要有关系,要么继承,要么实现,存在重写(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代码实现多态:
<?php abstract 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()); ?>
相关文章推荐
- 浅谈多态以及php的实现方法
- Lua的类实现继承、多态以及setmetatable方法
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- PHP实现进程锁的方法以及详解
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- Java中方法多态以及多接口实现
- Lua的类实现继承、多态以及setmetatable方法
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)(转)
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- 利用Matrix对图片进行变换以及实现动画方法浅谈
- Lua的类实现继承、多态以及setmetatable方法
- 浅谈DNS基本原理以及实现方法(一) 推荐
- php生成短网址的思路以及实现方法
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- PHP变量的内存布局、实现方法以及作用域
- Lua的类实现继承、多态以及setmetatable方法
- 浅谈DNS基本原理以及实现方法(二) 推荐
- Lua的类实现继承、多态以及setmetatable方法
- 《转》 浅谈C# 多态的魅力(虚方法,抽象,接口实现)
- 浅谈C# 多态的魅力(虚方法,抽象,接口实现)