PHP之OOP: 编程思想从过程到对象!
本文转贴李明老师的博客:
http://student.youkuaiyun.com/space.php?uid=129820&do=blog&id=32945
虽然本文写的是关于PHP开发语言编程,但是关于OOP编程思想却是不分开发语言品种的,觉得李老师写的这篇文章以生活中的平常事为例子,生动,容易理解,故收藏起来反复学习:
有一个人走进商店,他对老板说:我想要一个东西,这个东西呢,它是圆形的,是甜甜的,上面有奶油,并且有一些水果在上面,可以插蜡烛... 他繁复得叙述的这个什么东西,究竟是什么呢?其实我不说大家也猜得到:他想要一个生日蛋糕。
现实生活中,我们不必描述所有一切事物的制作过程,因为有时,我只想要这个事物,并不关心它的过程。
代码世界中,我们也可以这样。
Object Oriented Programming,面向对象的程序设计,使我们的开发变得不再那么复杂,并大大增加了程序的灵活性和可扩展性。如果你尚未用OOP思想来完善你的程序设计,那你真的OUT了。
PHP中的面向对象,是从PHP5开始完善的,之前的版本本质上还是面向过程的。面向过程只为我们程序提供了一定程度的代码重用。然而,没有OO的特质,依然不妨碍我们的PHP开发人员运用这种优秀的编程思想,一些含有伪OO设计的面向过程代码依然出现在我们的项目中,但是由于本质上仍是面向过程的,可读性不是很好。
实现面向对象,首先需要知道的两个重要的概念就是类和对象。
实例1:类和对象
<?php class Cake{ public $shape;//蛋糕的形状 public $cream;//奶油的量 public $eggs; //鸡蛋的量 public $water;//水的量 }
$cake1 = new Cake(); $cake1 ->shape= "circle"; $cake1 ->cream= "500g"; $cake1 ->eggs = 5;
echo $cake1 ->shape; echo $cake1 ->cream; echo $cake1 ->eggs; ?> |
现在我们有了一个制作蛋糕的菜谱(类),里面当然要有制作这个蛋糕需要什么原材料(成员属性),还要告诉我们如何去做(成员方法),但是有了这些,我们还没有拥有一个实实在在的蛋糕(对象),只有当我们照着菜谱上写的,把原材料备齐,照着方法一步一步去做,方可的到这个这个蛋糕(对象的实例化)。
有了这些还不够,我们都知道面向对象的三大特性:封装、继承、多态。实现良好的类有时还需要用到模式等等。而在这些之中,封装的足够好的类,可以将我们系统的功能实现模块化,这是优秀的OO设计重要特性之一,可以帮助我们更好的实现网站的维护。
实例2:封装
<?php class Cake{ public $shape;//蛋糕的形状 public $cream;//奶油的量 public $eggs; //鸡蛋的量 public $water;//水的量 public $bakeTime;//烤制时间 public $others;//其他配料 public function makeCake(){ $cakeBase = $this->water."水加".$this->egg."个鸡蛋和".$this->others."用力搅拌".$this->bakeTime; $cake = "将".$cakeBase."切成".$this->shape.",加入".$this->cream."奶油"; return $cake; } }
$cake1 = new Cake(); $cake1 ->shape = "circle"; $cake1 ->cream = "500g"; $cake1 ->eggs = 5; $cake1 ->water = "1L"; $cake1 ->bakeTime = "50m"; $cake1 ->others = "suger,butter";
?> |
我们把如何制作都放入makeCake()方法中,我不需要知道内部实现,如同我不需要跟蛋糕店老板说全部制作过程,只需要告诉他:我要做一个蛋糕:)
实例中的$cake1,就是我们得到的可口蛋糕啦,和抽象的类不一样,它是实实在在存在在内存中的。
等等,还没有完,现在我们的高级面点师来了,他知道如何去做。
实例3:对象的调用
<?php class Baker{ public $name; //面点师的名字 public function makeCake(){ $cake1 = new Cake(); $cake1 ->shape = "circle"; $cake1 ->cream = "500g"; $cake1 ->eggs = 5; $cake1 ->water = "1L"; $cake1 ->bakeTime = "50m"; $cake1 ->others = "suger,butter";
} }
$theBaker = new Baker(); $theBaker ->name = "John";
?> |
实际生活中也是一样,对象和对象之间的交互永不会停止,我们所要做的,就是让对象和对象间的关系足够清新,让类外部代码足够的少。
只是这样当然还是不够,类规定了对象,那谁来规定类呢?
答案当然是接口,接口是一种特殊的抽象类。
在使用接口时,请尝试避免直接引用实现类。相反,使用对象外部的内容可以提供正确的实现。如果你的类将装入基于某些逻辑的实现,它仍然需要获取所有实现类的定义,并且那样做也无法取得任何效果。
初识接口总是会想何时使用接口才会是最佳时机,或许这个问题待到你接触多了OO思想后就会某天如深夜醒脑般恍然大悟,想要设计良好的类诞生,接口是那么的必然和自然。并且在PHP单继承的特性下,只有接口技术才可以真正做到一次性实现多个规范,这也被我们成为单继承,多实现。即extends只能继承一个父类,而implements可以实现多个接口。
当然,避免滥用接口也是良好的编程习惯之一,毕竟只要写在程序中的接口,就会对我之后的代码产生一定的约束力,如果不是必然,为什么写进这个必须执行的“法律”中去呢?
实例4:实现接口
<?php interface Person{ funciton setName(); funciton work(); function laugh(); } class Baker implements Person{ public $name; public function setName($name){ $this->name = $name; }
public function work(){ $cake1 = new Cake(); $cake1 ->shape = "circle"; $cake1 ->cream = "500g"; $cake1 ->eggs = 5; $cake1 ->water = "1L"; $cake1 ->bakeTime = "50m"; $cake1 ->others = "suger,butter"; $this ->laugh(); } public function laugh(){ echo "Laughing out!"; } }
$theBaker = new Baker(); $theBaker ->setName("John");
?> |
每个人都有工作,现在例子中的John($theBaker),他是个面点师(class Baker),面点师又必然是一个人(interface Person),一定有一份工作(function work()),一定会笑(function laugh()),也一定在一个孩童时就被取了个名字(function setName()),当然,去除掉一种情况,就是,他是个野人。不过野人也有名字(或许他叫狼人),野人也要工作(他要打猎养活自己),他也会笑(可能是打猎时见到了一只野兔?)。总之,他只要还是人类,就要从接口Person来实现。
从过程到对象,是一个进步,也是一种思想,它让我们从逻辑中解放出来,看到一个个实实在在的实体,当你将这种思想运用于实践时,就会慢慢感叹编程前辈的无比智慧和奇思妙想。