虽然之前我们已经学习了PHP语言的开发基础,但是应用这些知识来开发项目还远远不够,因为我们在实际的项目中都需要使用“面向对象”的写法来进行编程,如果只懂得基本语法却没有面向对象的编程思想是万万不行的。所以接下来我们将为大家介绍在PHP语言中,我们是如何使用面向对象的编程思路来进行开发的。
其实PHP语言的面向对象编程思路和Java非常相似,对象(Object)、类(Class)、抽象类(Abstract Class)、接口(Interface)以及MVC三层封装的用法都大同小异,由于篇幅限制,相同的地方将不再赘述,这里主要给大家介绍一下不同的地方,下面我们将结合面向对象编程思想中的几个重要概念来分析一下。
1. 抽象性
要认识面向对象的思想,首先需要理解什么是对象。对象是面向对象编程的基本元素,对象可以是我们需要研究的任何元素,可以是具体的物品,也可以是抽象的事物。比如我们在研发一个后台管理系统时,管理员是一个对象,后台权限也是一个对象。这就是抽象的基本思路,就这点来说,不管我们使用的是什么语言,思考方式应该是一样的。
此外,对象在程序代码中是用“类”(Class)来表示的,每个类都需要具备“唯一性”的特征,在大部分语言中都使用“命名空间”来解决这个问题;然而对于PHP来说,我们通常使用一种“约定”或者“规范”来解决这个问题,比如在PHP的一些大型类库(如Zend Framework)中我们通常把类名和目录名对应起来,Zend/Db/Exception.php文件的类名是Zend_Db_Exception,这种方式在项目中还是比较实用的。
2. 继承性
继承性是面向对象思想中最基础、最重要的特点之一,也正是因为对象的继承性才延伸出了“抽象”和“封装”等面向对象的设计方法。在PHP语言中我们同样使用私有(private)、保护(protected)和公共(public)关键字来设定类、属性和方法的权限,关于这些基础概念的基本用法大家可以到网上收罗到一大堆,这里不再赘述。下面我们将以一个PHP代码为例给大家讲解一下使用要领,见代码清单3-8。
代码清单 3-8
// 基础抽象类
abstract class Base_Customer {
// 私有属性
private $_name = '';
// 私有方法
private function _checkName ($name) {
return is_string($name) ? $name : false;
}
// 保护方法
protected function _formatName ($name) {
return (string) $name;
}
// 公用方法
public function setName ($name) {
$this->_name = $this->_formatName($name);
}
// 公用方法
public function getName () {
return $this->_checkName($this->_name);
}
// 抽象方法,子类需要实现
abstract public function setPassword();
// 抽象方法,子类需要实现
abstract public function getPassword();
}
上述实例代码中我们定义了一个名为Base_Customer的用户抽象基类,里面有一个名为“$_name”的私有属性,表示用户的名字;为了让外部能够访问这个属性,我们添加了读取名字getName和设置名字setName两个public方法,供外部程序调用。另外,此类还有一个private方法_checkName用于确认用户名字是否有误,一个protected方法_formatName用于保证名字正确性。在代码的最后我们还定义了两个抽象方法,设置密码setPassword和取得密码getPassword两个方法,用于对用户的密码进行操作,这两个方法都需要在子类中实现的。从以上代码中我们可以看到PHP语言里大部分面向对象编程的写法,大家可以好好理解一下。
3. 多态性
多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果,这个特性进一步增加了面向对象编程思想的灵活性和重用性。我们知道,重载是实现多态性最常见的方法,比如代码清单3-9就是使用Java语言来使用重载的实例代码。
代码清单 3-9
class Demo{
// 成员变量
int a, b, c;
// 构造函数
public Demo() {}
// 重载构造函数
public Demo(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
// 成员方法
int sum() {
return a + b + c;
}
// 重载成员方法
int sum(int d) {
return a + b + c + d;
}
}
我们看到上面用Java语言实现的Demo类中,构造方法Demo被定义了两次,根据传入参数的不同,方法逻辑也有所不同;另外,类中的成员方法sum也被定义了两次,同样可以根据不同的参数来处理不同的逻辑。但是这是Java的做法,在PHP中我们也可以这样做吗?答案是否定的,因为PHP语言不允许出现相同名称的方法,即使在同一个类中。那么我们应该怎么做呢?看看代码清单3-10中是怎么写的吧。
代码清单 3-10
class Demo {
// 成员变量
public $a, $b, $c;
// 构造方法
public function Demo ($a = 0, $b = 0, $c = 0) {
if ($a) $this->a = $a;
if ($b) $this->b = $b;
if ($c) $this->c = $c;
}
// 成员方法
public function sum ($d = 0) {
if ($d) {
return $this->a + $this->b + $this->c + $d;
} else {
return $this->a + $this->b + $this->c;
}
}
}
我们可以看到,以上的PHP代码同样实现了一个Demo类,此类含有和前面Java版的Demo类同样的成员变量,却只有一个构造方法Demo和成员方法sum;但是有趣的是,通过对这两个方法的逻辑分析,我们会发现这里同样根据参数的不同实现了不同的逻辑。这是为什么呢?答案其实很简单,就是因为PHP允许设置参数的默认值。这种PHP特有的功能帮助我们用另外一种方式实现了多态性。
以上我们介绍的PHP面向对象编程的基础知识,需要大家好好理解一下,因为在后面我们即将给大家介绍的微博应用实例中,这些用法将会被广泛使用;另外,在本章最后介绍的Hush Framework框架中我们也会接触到这些用法。当然,培养成熟的面向对象的编程思想绝不是一朝一夕的事情,需要大家在学习的时候边实践边思考,最好能阅读一些比较优秀的代码,当然本书后面将要给大家介绍的微博项目实例代码也是个很不错的面向对象编程的代码范本,如果大家能通过本书将其理解透彻,绝对会受益匪浅。