韶华将逝,雄心未已;欲与众君,共习此技.
《PHP和MySQL Web开发》学习笔记(八)
上一篇 / 下一篇 2007-07-24 08:11:07 / 天气: 晴朗 / 心情: 平静 / 个人分类:PHP & MySQL
6.1.1 类和对象
面向对象软件由一系列具有属性和操作的自包含对象组成,这些对象之间能够交互,从而达到我们的要求。对象的属性是与对象相关的特性或变量。对象的操作则是对象可以执行的、用来改变其自身或对外部产生影响的方法、行为或函数(属性可以与成员变量和特性这些词交替使用,而操作也可以与方法交替使用)。
面向对象软件的一个重要优点是支持和鼓励封装的能力——封装也叫数据隐藏。从本质上说,访问一个对象中的数据只能通过对象的操作来实现,对象的操作也就是对象的接口。
一个对象的功能取决于对象使用的数据。在不改变对象的接口的情况下,能很容易地修改对象实现的细节,从而提高性能、添加新性能或修复bug。在整个项目中,修改接口可能会带来一些连锁反应,但是封装允许在不影响项目其他部分的情况下进行修改或修复bug。
在软件开发的其他领域中,面向对象已经成为一种标准,而面向功能或过程的软件则被认为是过时的。不幸的是,由于种种原因,大多数Web脚本仍然是使用一种面向功能的特殊方法来设计和编写的。
存在这种情况的原因是多方面的:一方面,多数Web项目相对比较小而且直观。我们可以拿起锯子就做一个木制调味品的架子而不用仔细规划其制作方法。同样,对于Web项目,由于网站规模太小,设计者也可以这样不经过仔细规划而成功完成大多数Web项目。然而,如果不经过计划就拿起锯子来建造一栋房子,房子的质量就没有保证了。同样的道理也适用于大型的软件项目——如果我们要想保证其质量的话。
在面向对象的软件中,对象是一个被保存数据和操作这些数据的操作方法的唯一、可标识的集合。
对象可以按类进行分类。类是表示彼此之间可能互不相同,但是必须具有一些共同点的对象集合。虽然类所包含的对象可能具有不同属性值,但是,这些对象都具有以相同方式实现的相同操作以及表示相同事物的相同属性。
面向对象软件由一系列具有属性和操作的自包含对象组成,这些对象之间能够交互,从而达到我们的要求。对象的属性是与对象相关的特性或变量。对象的操作则是对象可以执行的、用来改变其自身或对外部产生影响的方法、行为或函数(属性可以与成员变量和特性这些词交替使用,而操作也可以与方法交替使用)。
面向对象软件的一个重要优点是支持和鼓励封装的能力——封装也叫数据隐藏。从本质上说,访问一个对象中的数据只能通过对象的操作来实现,对象的操作也就是对象的接口。
一个对象的功能取决于对象使用的数据。在不改变对象的接口的情况下,能很容易地修改对象实现的细节,从而提高性能、添加新性能或修复bug。在整个项目中,修改接口可能会带来一些连锁反应,但是封装允许在不影响项目其他部分的情况下进行修改或修复bug。
在软件开发的其他领域中,面向对象已经成为一种标准,而面向功能或过程的软件则被认为是过时的。不幸的是,由于种种原因,大多数Web脚本仍然是使用一种面向功能的特殊方法来设计和编写的。
存在这种情况的原因是多方面的:一方面,多数Web项目相对比较小而且直观。我们可以拿起锯子就做一个木制调味品的架子而不用仔细规划其制作方法。同样,对于Web项目,由于网站规模太小,设计者也可以这样不经过仔细规划而成功完成大多数Web项目。然而,如果不经过计划就拿起锯子来建造一栋房子,房子的质量就没有保证了。同样的道理也适用于大型的软件项目——如果我们要想保证其质量的话。
在面向对象的软件中,对象是一个被保存数据和操作这些数据的操作方法的唯一、可标识的集合。
对象可以按类进行分类。类是表示彼此之间可能互不相同,但是必须具有一些共同点的对象集合。虽然类所包含的对象可能具有不同属性值,但是,这些对象都具有以相同方式实现的相同操作以及表示相同事物的相同属性。
6.1.2 多态性
面向对象的编程语言必须支持多态性,多态性的意思是指不同的类对同一操作可以有不同的行为。例如,如果定义了一个“汽车”类和一个“自行车”类,二者可以具有不同的“移动”操作。对于现实世界的对象,这并不是一个问题。我们不可能将自行车的移动与汽车的移动相混淆。然后,编程语言并不能处理现实世界的这种基本常识,因此语言必须支持多态性,从而可以知道将哪个移动操作应用于一个特定的对象。
多态性与其说是对象的特性,不如说是行为的特性。在PHP中,只有类的成员函数可以是多态的。这可与现实世界的自然语言的动词做比较,后者相当于成员函数。这些动词只描述了普遍行为,因为我们不知道这些行为应该作用于哪种对象(这种对对象和行为的抽象是人类智慧的一个典型特征)。一旦行为作用的对象确定下来,动词就可以和一系列特定的行为联系起来。
面向对象的编程语言必须支持多态性,多态性的意思是指不同的类对同一操作可以有不同的行为。例如,如果定义了一个“汽车”类和一个“自行车”类,二者可以具有不同的“移动”操作。对于现实世界的对象,这并不是一个问题。我们不可能将自行车的移动与汽车的移动相混淆。然后,编程语言并不能处理现实世界的这种基本常识,因此语言必须支持多态性,从而可以知道将哪个移动操作应用于一个特定的对象。
多态性与其说是对象的特性,不如说是行为的特性。在PHP中,只有类的成员函数可以是多态的。这可与现实世界的自然语言的动词做比较,后者相当于成员函数。这些动词只描述了普遍行为,因为我们不知道这些行为应该作用于哪种对象(这种对对象和行为的抽象是人类智慧的一个典型特征)。一旦行为作用的对象确定下来,动词就可以和一系列特定的行为联系起来。
6.1.3 继承
继承允许我们使用子类在类之间创建层次关系。子类将从它的超类继承属性和操作。
通过继承,我们可以在已有类的基础上创建新类。根据实际需要,可以从一个简单的基类开始,派生出更复杂、更专门的类。这样,可以使代码具有更好的可重用性。这就是面向对象方法的一个重要优点。
如果操作可以在一个超类中编写一遍而不需要在每个子类中都编写,那么就可以利用继承省去大量重复的编码工作。这也使得我们可以对现实世界的各种关系建立更精确的模型。如果类之间的相互关系可以用“是”来描述的话,就有点类似于我们这里的“继承”。例如,句子“汽车是交通工具”有意义,而句子“交通工作是汽车”则没有意义(因为并不是所有的交通工具都是汽车)。因此,汽车可以继承交通工具。
继承允许我们使用子类在类之间创建层次关系。子类将从它的超类继承属性和操作。
通过继承,我们可以在已有类的基础上创建新类。根据实际需要,可以从一个简单的基类开始,派生出更复杂、更专门的类。这样,可以使代码具有更好的可重用性。这就是面向对象方法的一个重要优点。
如果操作可以在一个超类中编写一遍而不需要在每个子类中都编写,那么就可以利用继承省去大量重复的编码工作。这也使得我们可以对现实世界的各种关系建立更精确的模型。如果类之间的相互关系可以用“是”来描述的话,就有点类似于我们这里的“继承”。例如,句子“汽车是交通工具”有意义,而句子“交通工作是汽车”则没有意义(因为并不是所有的交通工具都是汽车)。因此,汽车可以继承交通工具。
6.2 在PHP中创建类、属性和操作
当创建一个PHP类的时候,必须使用关键词“class”。
当创建一个PHP类的时候,必须使用关键词“class”。
6.2.1 类的结构
一个最小的、最简单的类定义如下所示:
class classname
{
}
为了使以上类具有实用性,类需要添加一些属性和操作。通过在类的定义中使用关键词“var”来声明变量,可以创建属性。通过在类定义中声明函数,可以创建类的操作。
一个最小的、最简单的类定义如下所示:
class classname
{
}
为了使以上类具有实用性,类需要添加一些属性和操作。通过在类的定义中使用关键词“var”来声明变量,可以创建属性。通过在类定义中声明函数,可以创建类的操作。
6.2.2 构造函数
大多数类都有一种称为构造函数的特殊操作。当创建一个对象时,它将调用构造函数,通常,这将执行一些有用的初始化任务:例如,设置属性的初始值或者创建该对象需要的其他对象。
构造函数的声明与其他操作的声明一样,只是其名称必须是__construct()。这是PHP5中的变化。在以前的版本中,构造函数的名称必须与类名称相同。为了向下兼容,如果一个类中没有名为__construct()的方法,PHP将搜索一个与类名称相同的方法。
虽然我们可以手动地调用构造函数,但是其主要用途是在创建一个对象时自动调用。
如今,PHP5已经支持函数重载,这就意味着可以提供多个具有相同名称以及不同数量或类型的参数的函数。
大多数类都有一种称为构造函数的特殊操作。当创建一个对象时,它将调用构造函数,通常,这将执行一些有用的初始化任务:例如,设置属性的初始值或者创建该对象需要的其他对象。
构造函数的声明与其他操作的声明一样,只是其名称必须是__construct()。这是PHP5中的变化。在以前的版本中,构造函数的名称必须与类名称相同。为了向下兼容,如果一个类中没有名为__construct()的方法,PHP将搜索一个与类名称相同的方法。
虽然我们可以手动地调用构造函数,但是其主要用途是在创建一个对象时自动调用。
如今,PHP5已经支持函数重载,这就意味着可以提供多个具有相同名称以及不同数量或类型的参数的函数。
6.2.3 析构函数
与构造函数相对的就是析构函数。析构函数是PHP5新添加的内容。它们允许在销毁一个类之前执行一些操作或完成一些功能,这些操作或功能通常在所有对该类的引用都被重置或超出作用域时自动发生。
与构造函数的名称类似,一个类的析构函数名称必须是__destruct()。析构函数不能带有任何参数。
与构造函数相对的就是析构函数。析构函数是PHP5新添加的内容。它们允许在销毁一个类之前执行一些操作或完成一些功能,这些操作或功能通常在所有对该类的引用都被重置或超出作用域时自动发生。
与构造函数的名称类似,一个类的析构函数名称必须是__destruct()。析构函数不能带有任何参数。
6.3 类的实例化
在声明一个类后,需要创建一个对象——一个特定的个体,即类的一个成员——并使用这个对象。这也叫创建一个实例或实例化一个类。可以使用关键词“new”来创建一个对象。需要指定创建的对象是哪一个类的实例,并且通过构造函数提供任何所需的参数。
在声明一个类后,需要创建一个对象——一个特定的个体,即类的一个成员——并使用这个对象。这也叫创建一个实例或实例化一个类。可以使用关键词“new”来创建一个对象。需要指定创建的对象是哪一个类的实例,并且通过构造函数提供任何所需的参数。
6.4 使用类的属性
在一个类中,可以访问一个特殊的指针——$this。如果当前类的一个属性为$atrribute,则当在该类中通过一个操作设置或访问该变量时,可以使用$this->atrribute来引用。
是否可以在类的外部访问一个属性是由访问修饰符来确定的。
通常,从类的外部直接访问类的属性是糟糕的想法。面向对象方法的一个优点就是鼓励使用封装。可以通过使用__get() 和__set()函数来实现对属性的访问。如果不直接访问一个类的属性而是编写访问函数,那么可以通过一段代码执行所有的访问。
请注意,__get()函数带有一个参数——属性的名称——并且返回该属性的值。__set()函数需要两个参数,分别是:要被设置值的属性名称和要被设置的值。
我们并不会直接访问这些函数。这些函数名称前面的双下划线表明在PHP中这些函数具有特殊的意义,就像__construct()函数和__destruct()函数一样。
可以用__get()函数和__set()函数来检查和设置任何属性的值。
提供访问器函数的理由就是这么简单:我们只使用一段代码来访问特定的属性。
只有一个访问入口,就可以实现对要保存的数据进行检查,这样可以确保被保存的数据是有意义的数据。
通过单一的访问入口,可以方便地改变潜在的程序实现。如果由于某种原因,需要改变属性的保存方式,访问器函数允许我们只要修改一处代码即可完成此工作。
在一个类中,可以访问一个特殊的指针——$this。如果当前类的一个属性为$atrribute,则当在该类中通过一个操作设置或访问该变量时,可以使用$this->atrribute来引用。
是否可以在类的外部访问一个属性是由访问修饰符来确定的。
通常,从类的外部直接访问类的属性是糟糕的想法。面向对象方法的一个优点就是鼓励使用封装。可以通过使用__get() 和__set()函数来实现对属性的访问。如果不直接访问一个类的属性而是编写访问函数,那么可以通过一段代码执行所有的访问。
请注意,__get()函数带有一个参数——属性的名称——并且返回该属性的值。__set()函数需要两个参数,分别是:要被设置值的属性名称和要被设置的值。
我们并不会直接访问这些函数。这些函数名称前面的双下划线表明在PHP中这些函数具有特殊的意义,就像__construct()函数和__destruct()函数一样。
可以用__get()函数和__set()函数来检查和设置任何属性的值。
提供访问器函数的理由就是这么简单:我们只使用一段代码来访问特定的属性。
只有一个访问入口,就可以实现对要保存的数据进行检查,这样可以确保被保存的数据是有意义的数据。
通过单一的访问入口,可以方便地改变潜在的程序实现。如果由于某种原因,需要改变属性的保存方式,访问器函数允许我们只要修改一处代码即可完成此工作。
6.5 使用private和public关键字控制访问
PHP5引入了访问修饰符。它们可以控制属性和方法的可见性。通常,它们旋转在属性和方法声明之前。PHP5支持如下3种访问修饰符:
默认选项是public,这意味着如果没有为一个属性或方法指定访问修饰符,它将是public。公有的属性或方法可以在类的内部和外部进行访问。
private访问修饰符意味着被标记的属性或方法只能在类的内部进行访问。如果没有使用__get()和__set()方法,你可能会对所有的属性都使用这个关键字。也可以选择使得部分方法成为私有的,例如,如果某些方法只是在类内部使用的工具性函数。私有的属性和方法将不会被继承。
protected访问修饰符意味着被标记的属性或方法只能在类内部进行访问。它也存在于任何子类。
类成员可以不添加public关键字,因为它是默认的访问修饰符,但是如果使用了其他修饰符,添加public修饰符将便于代码理解和阅读。
PHP5引入了访问修饰符。它们可以控制属性和方法的可见性。通常,它们旋转在属性和方法声明之前。PHP5支持如下3种访问修饰符:
默认选项是public,这意味着如果没有为一个属性或方法指定访问修饰符,它将是public。公有的属性或方法可以在类的内部和外部进行访问。
private访问修饰符意味着被标记的属性或方法只能在类的内部进行访问。如果没有使用__get()和__set()方法,你可能会对所有的属性都使用这个关键字。也可以选择使得部分方法成为私有的,例如,如果某些方法只是在类内部使用的工具性函数。私有的属性和方法将不会被继承。
protected访问修饰符意味着被标记的属性或方法只能在类内部进行访问。它也存在于任何子类。
类成员可以不添加public关键字,因为它是默认的访问修饰符,但是如果使用了其他修饰符,添加public修饰符将便于代码理解和阅读。
6.6 类操作的调用
可以像调用其他函数一样调用操作:通过使用克名称以及将所有所需的参数放置在括号中,因为这些操作属于一个对象而不是常规的函数,所以需要指定它们所属的对象。对象名称的使用方法与对象属性一样。
可以像调用其他函数一样调用操作:通过使用克名称以及将所有所需的参数放置在括号中,因为这些操作属于一个对象而不是常规的函数,所以需要指定它们所属的对象。对象名称的使用方法与对象属性一样。
6.7 在PHP中实现继承
如果类是另一个类的子类,可以用关键词“extends”来指明其继承关系。
值得注意的是,继承是单方向的。子类可以从风类或超类继承特性,但父类却不能从子类继承特性。
如果类是另一个类的子类,可以用关键词“extends”来指明其继承关系。
值得注意的是,继承是单方向的。子类可以从风类或超类继承特性,但父类却不能从子类继承特性。
6.7.1 通过继承使用private和protected访问修饰符控制可见性
可以使用private和protected访问修饰符来控制需要继承的内容。如果一个属性或方法被指定为private,它将不能被继承。如果一个属性或方法被指定为protected,它将在类外部不可见(就像一个private元素),但是可以被继承。
可以使用private和protected访问修饰符来控制需要继承的内容。如果一个属性或方法被指定为private,它将不能被继承。如果一个属性或方法被指定为protected,它将在类外部不可见(就像一个private元素),但是可以被继承。
6.7.2 重载
在子类中,再次声明相同的属性和操作也是有效的,而且在有些情况下这将会是非常有用的。我们可能需要在子类中给某个属性赋予一个与其超类属性不同的缺省值,或者给某个操作赋予一个与其超类操作不同的功能,这就叫重载。
如果不使用替代,一个子类将继承超类的所有属性和操作。如果子类提供了替代定义,替代定义将有优先级并且重载初始定义。
parent关键字允许调用父类操作的最初版本。虽然调用了父类的操作,但是PHP将使用当前类的属性值。
继承可以是多重的。可以声明一个类C,它继承了类B,因此继承了类B和类B父类的所有特性。类C还可以选择重载和替换父类的那些属性和操作。
在子类中,再次声明相同的属性和操作也是有效的,而且在有些情况下这将会是非常有用的。我们可能需要在子类中给某个属性赋予一个与其超类属性不同的缺省值,或者给某个操作赋予一个与其超类操作不同的功能,这就叫重载。
如果不使用替代,一个子类将继承超类的所有属性和操作。如果子类提供了替代定义,替代定义将有优先级并且重载初始定义。
parent关键字允许调用父类操作的最初版本。虽然调用了父类的操作,但是PHP将使用当前类的属性值。
继承可以是多重的。可以声明一个类C,它继承了类B,因此继承了类B和类B父类的所有特性。类C还可以选择重载和替换父类的那些属性和操作。
6.7.3 使用final关键字禁止继承和重载
PHP5引入了final关键字。当在一个函数声明前面使用这个关键字时,这个函数将不能在任何子类中被重载。
也可以使用final关键字来禁止一个类被继承。
PHP5引入了final关键字。当在一个函数声明前面使用这个关键字时,这个函数将不能在任何子类中被重载。
也可以使用final关键字来禁止一个类被继承。
6.7.4 理解多重继承
少数的面向对象语言(最著名的就是C++和Smalltalk)支持多重继承,但是与大多数面向对象语言一样,PHP并不支持多重继承。也就是说,每个类都只能继承一个父类。一个父类可以有多少个子类并没有限制。
少数的面向对象语言(最著名的就是C++和Smalltalk)支持多重继承,但是与大多数面向对象语言一样,PHP并不支持多重继承。也就是说,每个类都只能继承一个父类。一个父类可以有多少个子类并没有限制。
6.7.5 实现接口
PHP5中引入了接口。接口可以看作是多重继承问题的解决方法,而且类似于其他面向对象编程语言所支持的接口实现,包括Java。
接口的思想是指定一个实现了该接口的类必须实现的一系列函数。
PHP5中引入了接口。接口可以看作是多重继承问题的解决方法,而且类似于其他面向对象编程语言所支持的接口实现,包括Java。
接口的思想是指定一个实现了该接口的类必须实现的一系列函数。
6.8 类的设计
6.9 编写类代码
通过PHP类创建页面的好处是显而易见的,通过用类完成了大部分工作,在创建页面的时候,我们就可以做更少的工作。在更新页面的时候,只要简单地更新类即可。通过继承,我们还可从最初的类派生出不同版本的类而不会破坏这些优势。
当然,就像现实生活中的事情一样,有所得必有所失,这些优点出现也伴随着一定的代码。用脚本创建网页要求更多计算机处理器的处理操作,因为它并不是简单地从硬盘载入静态HTML页然后再送到浏览器。在一个业务繁忙的网站中,处理速度是很重要的,应该尽量使用静态HTML网页,或者尽可能缓存脚本输出,从而减少在服务器上的载入操作。
通过PHP类创建页面的好处是显而易见的,通过用类完成了大部分工作,在创建页面的时候,我们就可以做更少的工作。在更新页面的时候,只要简单地更新类即可。通过继承,我们还可从最初的类派生出不同版本的类而不会破坏这些优势。
当然,就像现实生活中的事情一样,有所得必有所失,这些优点出现也伴随着一定的代码。用脚本创建网页要求更多计算机处理器的处理操作,因为它并不是简单地从硬盘载入静态HTML页然后再送到浏览器。在一个业务繁忙的网站中,处理速度是很重要的,应该尽量使用静态HTML网页,或者尽可能缓存脚本输出,从而减少在服务器上的载入操作。
6.10 理解PHP面向对象新的高级功能
6.10.1 提示:PHP4和PHP5的比较
在PHP4中,对象是按值传递的,而如今,对象是按引用传递的。按照这种方式编写代码将不会破坏任何已有的代码,而且事实上,许多程序员由于没有到这一点,编写了许多效率不高的代码。例如,如下所示的代码:$c = new myClass; 创建了一个新类并且将该类的实例复制给$c(事实上创建了两个拷贝,但是立即就会丢失其中一个拷贝的句柄)。如果假设对象是按引用传递的,尤其是在向函数传递对象时,这种行为可能会导致问题。
在默认情况下,大多数面向对象语言都是按引用传递对象的,如今PHP也是这种类型的编程语言。
另一个显著的差异就是以前的PHP版本无法间接引用由函数返回的对象,尤其是调用这些对象的方法。
在PHP4中,对象是按值传递的,而如今,对象是按引用传递的。按照这种方式编写代码将不会破坏任何已有的代码,而且事实上,许多程序员由于没有到这一点,编写了许多效率不高的代码。例如,如下所示的代码:$c = new myClass; 创建了一个新类并且将该类的实例复制给$c(事实上创建了两个拷贝,但是立即就会丢失其中一个拷贝的句柄)。如果假设对象是按引用传递的,尤其是在向函数传递对象时,这种行为可能会导致问题。
在默认情况下,大多数面向对象语言都是按引用传递对象的,如今PHP也是这种类型的编程语言。
另一个显著的差异就是以前的PHP版本无法间接引用由函数返回的对象,尤其是调用这些对象的方法。
6.10.2 使用Per-Class常量
PHP5引入了Per-Class常量的思想。这个常量可以在不需要初始化该类的情况下使用。
PHP5引入了Per-Class常量的思想。这个常量可以在不需要初始化该类的情况下使用。
6.10.3 实现静态方法
PHP5还引入了static关键字。该关键字适用于允许在未初始化类的情况下就可以调用的方法。这种方法等价于Per-Class常量的思想。
请注意,在一个静态方法中,不能使用this关键字。因为可能会没有可以引用的对象实例。
PHP5还引入了static关键字。该关键字适用于允许在未初始化类的情况下就可以调用的方法。这种方法等价于Per-Class常量的思想。
请注意,在一个静态方法中,不能使用this关键字。因为可能会没有可以引用的对象实例。
6.10.4 检查类的类型和类型提示
该特性也是PHP5新引入,提供了instanceof关键字和类型提示的概念。
instanceof关键字允许检查一个对象的类型。可以检查一个对象是否是特定类的实例,是否是从某个类继承或者是否实现了某个接口。instanceof关键字是一个高效率的条件操作符。
此外,PHP5新引入了类的类型提示的思想。通常,当在PHP中向一个函数传递一个参数时,不能传递该参数的类型。使用类类型提示,可以指定必须传入的参数类类型,同时,如果传入的参数类型不是指定的类型,将产生一个错误。类型检查等价于instanceof的作用。
该特性也是PHP5新引入,提供了instanceof关键字和类型提示的概念。
instanceof关键字允许检查一个对象的类型。可以检查一个对象是否是特定类的实例,是否是从某个类继承或者是否实现了某个接口。instanceof关键字是一个高效率的条件操作符。
此外,PHP5新引入了类的类型提示的思想。通常,当在PHP中向一个函数传递一个参数时,不能传递该参数的类型。使用类类型提示,可以指定必须传入的参数类类型,同时,如果传入的参数类型不是指定的类型,将产生一个错误。类型检查等价于instanceof的作用。
6.10.5 克隆对象
PHP5引入了clone关键字,该关键字允许复制一个已有的对象。例如:$c = clone $b; 将创建与对象$b具有相同类的拷贝,而且具有相同的属性值。
如果不需要克隆过来的默认行为,必须在基类中创建一个__clone()方法。这个方法类似于构造函数或析构函数,因为不会直接调用它。当以上例所示的方式使用clone关键字时,该方法将被调用。
__clone()方法的一个很好特性就是在使用默认行为创建一个拷贝后能够被调用,这样,在这个阶段,可以只改变希望改变的内容。
在__clone()方法中添加的最常见功能就是确保作为引用进行处理的类属性能够正确地复制。如果要克隆一个包含有对象引用的类,可能需要获得该对象的第二个拷贝,而不是该对象的第二个引用,因此这就是为什么要在__clone()方法中添加该代码的原因。
我们可能会选择在该方法中执行一些其他的操作,例如更新与该类相关的数据库记录。
PHP5引入了clone关键字,该关键字允许复制一个已有的对象。例如:$c = clone $b; 将创建与对象$b具有相同类的拷贝,而且具有相同的属性值。
如果不需要克隆过来的默认行为,必须在基类中创建一个__clone()方法。这个方法类似于构造函数或析构函数,因为不会直接调用它。当以上例所示的方式使用clone关键字时,该方法将被调用。
__clone()方法的一个很好特性就是在使用默认行为创建一个拷贝后能够被调用,这样,在这个阶段,可以只改变希望改变的内容。
在__clone()方法中添加的最常见功能就是确保作为引用进行处理的类属性能够正确地复制。如果要克隆一个包含有对象引用的类,可能需要获得该对象的第二个拷贝,而不是该对象的第二个引用,因此这就是为什么要在__clone()方法中添加该代码的原因。
我们可能会选择在该方法中执行一些其他的操作,例如更新与该类相关的数据库记录。
6.10.6 使用抽象类
抽象类也是PHP5引入的新特性。这些类不能被实例化。
PHP5还提供了抽象方法,这些方法只提供了一个方法的声明,但是不提供方法的具体实现。
抽象方法和抽象类主要用于复杂的类层次关系中,该层次关系需要确保每一个子类都包含并重载某些特定的方法,这也可以通过接口来实现。
抽象类也是PHP5引入的新特性。这些类不能被实例化。
PHP5还提供了抽象方法,这些方法只提供了一个方法的声明,但是不提供方法的具体实现。
抽象方法和抽象类主要用于复杂的类层次关系中,该层次关系需要确保每一个子类都包含并重载某些特定的方法,这也可以通过接口来实现。
6.10.7 使用__call()重载方法
在PHP中,用__call()方法来实现方法的重载。
方法的重载在许多面向对象编程语言中都是常见的,但是在PHP中却不是非常有用,因为我们习惯使用灵活的类型和(容易实现的)可选的函数参数。
__call()方法必须带用两个参数。第一个包含了被调用的方法名称,而第二个参数包含了传递给该方法的参数数组。
在PHP中,用__call()方法来实现方法的重载。
方法的重载在许多面向对象编程语言中都是常见的,但是在PHP中却不是非常有用,因为我们习惯使用灵活的类型和(容易实现的)可选的函数参数。
__call()方法必须带用两个参数。第一个包含了被调用的方法名称,而第二个参数包含了传递给该方法的参数数组。
6.10.8 使用__autoload()方法
另一个特殊的函数是__autoload()。它不是一个类方法,而是一个单独的函数;也就是说,可以在任何类声明之外声明这个函数。如果实现了这个函数,它将在实例化一个还没有被声明的类时自动调用。
__autoload()方法的主要用途是尝试包括或要求任何用来初始化所需类的文件。
另一个特殊的函数是__autoload()。它不是一个类方法,而是一个单独的函数;也就是说,可以在任何类声明之外声明这个函数。如果实现了这个函数,它将在实例化一个还没有被声明的类时自动调用。
__autoload()方法的主要用途是尝试包括或要求任何用来初始化所需类的文件。
6.10.9 实现迭代器和迭代
可以使用foreach()方法通过循环方式取出一个对象的所有属性,就像数组方式一样。
可以使用foreach()方法通过循环方式取出一个对象的所有属性,就像数组方式一样。
如果需要一些更加复杂的行为,可以实现一个iterator(迭代器)。要实现一个迭代器,必须将要迭代的类实现IteratorAggregate接口,并且定义一个能够返回该迭代类实例的getIterator方法。这个类必须实现Iterator接口,该接口提供了一系列必须实现的方法。
像这样使用Iterator类的原因就是即使潜在的实现发生了变化,数据的接口还是不会发生变化。
像这样使用Iterator类的原因就是即使潜在的实现发生了变化,数据的接口还是不会发生变化。
6.10.10 将类转换成字符串
如果在类中实现了一个__toString()函数,当尝试打印该类时,可以调用这个函数。
如果在类中实现了一个__toString()函数,当尝试打印该类时,可以调用这个函数。
6.10.11 使用Feflection(反射)API
反射是通过访问已有类和对象来找到类和对象的结构和内容的能力。当使用未知或文档不详的类时,这个功能就非常有用,例如使用经过编码PHP脚本。
反射是通过访问已有类和对象来找到类和对象的结构和内容的能力。当使用未知或文档不详的类时,这个功能就非常有用,例如使用经过编码PHP脚本。
6.11 下一章
相关阅读:
- 《PHP和MySQL Web开发》学习笔记(二) (jayson, 2007-6-23)
- 《PHP和MySQL Web开发》学习笔记(六) (jayson, 2007-7-11)
- javascript 数据类型转换 (redrangon, 2007-7-12)
- 原来JSON这么简单,哇哈哈 (redrangon, 2007-7-13)
- 《PHP和MySQL Web开发》学习笔记(七) (jayson, 2007-7-16)
- php中的header汇总[转载] (redrangon, 2007-7-21)
