介绍
PHP4已经可以足够的支持对象,并且在任何大的项目或者小的程序中都可以看到对象的应用, 但是通过PHP5对象的使用我们可以建立一个更大的项目。我们知道,对象既非常有用,也非常灵活,也就是个原因我们很多人都经常使用。
但是你如果对于类和对象知道的不是很多,那么希望这篇文章会给你启发。我将会带领大家复习类和对象的基础,讨论PHP5对象和类的几乎每一个特点。我们从基础开始,类的自定义和适用。
请注意这篇文章不是关于OOP(Object Orientated Programming)的,讲解的OOP也是很少一部分而已。尽管你将会在这里学会如何使用对象,但是OOP是一个不同的概念,需要一整个思维模式的改变。显然,那需要更加灵活的使用类和对象。
那么让我们开始吧。
基本概念
通过Wikipedia知道"A class describes a collection of encapsulated instance variables and methods (functions)",一个对类非常好的定义。一个类有自己的变量,叫做属性,自己的函数,叫做方法。一个类的基本结构就像这个:
<?php class MyCar { // Properties and methods go here } ?>我们现在已经有了一个完整的类,尽管他还不能做什么,也没有任何属性。那么我们就让我们的类做点什么。看下面的例子:
<?php class MyCar { function drive() { echo 'Vrooooom...'; } } ?>我们现在已经加了一个叫drive()的函数在我们的类中,他能够输出一段字符”Vroooom…“。一个类的函数我们通常叫他类的方法。
我们的类现在已经可以做些什么了,但是我们还是没有使用他,因为我们还没有建立类的一个实例。
为了能使用类,已经他的属性和方法,我们要使用‘new’关键字建立一个实例。通过类实例的建立,我们就可以建立一个对象了。看下面的例子:
<?php class MyCar { function drive() { echo 'Vrooooom...'; } } $porsche = new MyCar(); $porsche->drive(); ?>如你所见,我们使用‘new’建立了一个属于MyCar类的实例$porsche。然后通过$porsche使用了drive()这个方法。
请注意,这很重要,类和对象是完全不同的概念。一个对象是一个单独的,或者说有自己特点的类的实例。比如说$porsche就是一个对象。而MyCar就是一个类。
你只能建立一个MyCar类,如果你试图建立两个叫做MyCar的类的话,那么就会出错。
而另一方面,你却可以建立多个类的实例。看下面的例子:
<?php class MyCar { function drive() { echo 'Vrooooom...'; } } // Instance 1 $porsche = new MyCar(); $porsche->drive(); // Instance 2 $bmw = new MyCar(); $bmw->drive(); echo ''; // Instance 3 $volvo = new MyCar(); $volvo->drive(); echo ''; ?>在上面的例子中我们建立了三个MyCar类的实例,也就是说我们有三个对象 $porsche, $bmw 和$volvo。每个对象都有他自己的drive()方法。
就像我开始说的,一个类也可以有他自己的变量,叫做属性。看下面的例子:
<?php class MyCar { public $name; function drive() { echo 'Vrooooom...'. $this->name; } } ?>我们做了两处修改。第一,通过“public $name;”添加了一个叫做$name的公用属性.第二,我们修改了drive()方法,他现在输出$name属性的值。
可以看到,我们使用$this->name来指向$name属性。
$this变量代表了当前实例,只能在类的内部调用类的方法和属性的时候使用。
看下面关于$name属性和变量$this使用的例子:
<?php class MyCar { public $name; function drive() { echo 'Vrooooom...'. $this->name; } } // Instance 1 $porsche = new MyCar(); $porsche->name = 'Porsche'; $porsche->drive(); echo ''; // Instance 2 $bmw = new MyCar(); $bmw->name = 'BMW'; $bmw->drive(); echo ''; // Instance 3 $volvo = new MyCar(); $volvo->name = 'Volvo'; $volvo->drive(); echo ''; ?>运行上面的例子,你会看到每个对象的name属性是不同的。
构造函数/析构函数(Destruction)
建立一个类的同时,类中就会有2个特征方法可以使用了,他们就是构造函数和析构函数。在一个类的建立的同事就会主动去使用构造函数方法,他通常是用来初始化类的状态 。很典型的使用方法就是设置数据库的连接或者设置默认属性,下面我们举例说明如何使用构造函数:
<?php class MyCar { public $name; function __construct($name) { $this->name = $name; } function drive() { echo 'Vrooooom... ' . $this->name; } } $porsche = new MyCar('Porsche'); $porsche->drive(); ?>在上面的例子中,我们使用了构造函数来设置类的$name属性。如你所见,在建立一个类的实例的同时我们传入了一个参数。
而析构函数,是当对象被移除时用来运行的,通过unset()函数或者脚本的结束都可以移除实例。通常析构函数都是用来执行清除任务的,比如说数据库的关闭,保存数据到硬盘等等。
看下面使用析构函数的例子:
<?php class MyCar { public $name; function __construct($name) { $this->name = $name; } function __destruct() { echo '*crash* this car has been destroyed'; } function drive() { echo 'Vrooooom... ' . $this->name; } } // Instance 1 $porsche = new MyCar('Porsche'); $porsche->drive(); echo ''; unset($porsche); //脚本结束也会执行 __destruct() ?>继承
继承是类使用方法里最伟大的发明,我们可以通过继承一个类来得到类中所有的方法和属性。
看下面关于类继承的例子:
<?php class MyCar { public $name; function __construct($name) { $this->name = $name; } function drive() { echo 'Vroooom... ' . $this->name; } } class PorscheCar Extends MyCar { // Contains no properties or methods of its own } $boxster = new PorscheCar('Boxster 987'); $boxster->drive(); ?>'PorscheCar'类没有任何方法和属性,但是我们仍然可以使用drive()方法, 因为PorscheCar类继承了所有他父类MyCar的方法和属性。要继承一个类,就要使用Extend关键字,就像我们在例子中所看到的。
我们也可以在子类中重新定义类的方法来覆盖父类中的同名方法。
通过这种方法我们可以定义一个一般的类,和几个特殊的子类。
例如:
<?php class MyCar { public $name; function __construct($name) { $this->name = $name; } function drive() { echo 'Vroooom...' . $this->name; } } class PorscheCar Extends MyCar { function drive() { echo 'VROOOOOOOOM... ' . $this->name; } } $boxster = new PorscheCar('Boxster 987'); $boxster->drive(); ?>如你所见,我们重定义的drive()函数输出了不同大的信息。
PHP5一个新的特征就是可以扩展父类的方法,重定义的完全替代。为了实现这点,需要用到“parent”:
<?php class MyCar { public $name; function __construct($name) { $this->name = $name; } function drive() { echo 'Vroooom... ' . $this->name; } } class PorscheCar Extends MyCar { function drive() { echo 'VROOOOOOOOM... ' . $this->name; echo ''; // Call original method from parent class parent::drive(); } } $boxster = new PorscheCar('Boxster 987'); $boxster->drive(); ?>输出结果:
VROOOOOOOOM... Boxster 987
Vroooom... Boxster 987