phpClass文档格式.docx

上传人:b****5 文档编号:18890829 上传时间:2023-01-02 格式:DOCX 页数:27 大小:502.51KB
下载 相关 举报
phpClass文档格式.docx_第1页
第1页 / 共27页
phpClass文档格式.docx_第2页
第2页 / 共27页
phpClass文档格式.docx_第3页
第3页 / 共27页
phpClass文档格式.docx_第4页
第4页 / 共27页
phpClass文档格式.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

phpClass文档格式.docx

《phpClass文档格式.docx》由会员分享,可在线阅读,更多相关《phpClass文档格式.docx(27页珍藏版)》请在冰豆网上搜索。

phpClass文档格式.docx

这是一个好主意,特别当你愿意与别人分享你的代码的时候。

  有关对象的想法是计算机科学上最令人兴奋的概念之一。

开始很难掌握它,但我可以保证,一旦你掌握了它,用它的思维来思考将会非常自然。

第二节对象模型

PHP5有一个单重继承的,限制访问的,可以重载的对象模型.本章稍后会详细讨论的”继承”,包含类间的父-子关系.另外,PHP支持对属性和方法的限制性访问.你可以声明成员为private,不允许外部类访问.最后,PHP允许一个子类从它的父类中重载成员。

PHP4中没有private,只有public.private对于更好地实现封装很有好处。

  PHP5的对象模型把对象看成与任何其它数据类型不同,通过引用来传递.PHP不要求你通过引用(reference)显性传递和返回对象.在本章的最后将会详细阐述基于句柄的对象模型.它是PHP5中最重要的新特性。

  有了更直接的对象模型,基于句柄的体系有附加的优势:

效率提高,占用内存少,并且具有更大的灵活性。

  在PHP的前几个版本中,脚本默认复制对象.现在PHP5只移动句柄,需要更少的时间.脚本执行效率的提升是由于避免了不必要的复制.在对象体系带来复杂性的同时,也带来了执行效率上的收益.同时,减少复制意味着占用更少的内存,可以留出更多内存给其它操作,这也使效率提高.

基于句柄,就是说两个对象可以指向同一块内存,既减少了复制动作,又减少对内存的占用。

  Zand引擎2具有更大的灵活性.一个令人高兴的发展是允许析构--在对象销毁之前执行一个类方法.这对于利用内存也很有好处,让PHP清楚地知道什么时候没有对象的引用,把空出的内存分配到其它用途。

 

第三节定义一个类

  当你声明一个类,你需要列出对象应有的所有变量和所有函数—被称为属性和方法.3.1.1中显示了一个类的构成.注意在大括号({})内你只能声明变量或者函数.3.1.2中显示了如何在一个类中定义三个属性和两个方法.

3.1.1

3.1.2

  

当你声明属性,你不需要指明数据类型.变量可能是整型,字符串或者是另一个对象,这取决于实际情况.在声明属性时增加注释是一个好主意,标记上属性的含义和数据类型.

  当你声明一个方法,你所做的和在类外部定义一个函数是一样的.方法和属性都有各自的命名空间.这意味着你可以安全地建立一个与类外部函数同名的方法,两者不会冲突.例如,一个类中可以定义一个名为date()的方法.但是你不能将一个方法命名为PHP的关键字,如for或者while.

  类方法可能包含PHP中所谓的typehint.Typehint是另一个传递参数给方法的类的名字.如果你的脚本调用方法并传递一个不是类的实例的变量,PHP将产生一个”致命(fatal)错误”.你可能没有给其它类型给出typehint,就像整型,字符串,或者布尔值.在书写的时候,typehint是否应当包含数组类型仍存在争议.

  Typehint是测试函数参数或者运算符的实例的数据类型的捷径.你可能总是返回这个方法.确认你强制让一个参数必须是哪种数据类型,如整型.3.2.1确保编译类只产生Widget的实例.

3.2.1

除了传递参数的变量外,方法含有一个特殊的变量.它代表类的个别实例.你应当用这个来指向对象的属性和其它方法.一些面向对象的语言假设一个不合格的变量提交给本地属性,但在PHP中方法的任何变量只是在方法的一定范围内.注意在User类的构造函数中这个变量的使用(3.1.2).

  PHP在属性和方法声明前定义一个访问限定语,如public,private和protected.另外,你可以用”static”来标记一个成员.你也可以在类中声明常量.本章稍后会有不同访问方式的相关讨论.

  你可以在一行中列出相同访问方式的几个属性,用逗号来分隔它们.在3.1.2中,User类有两个private属性--$password和$lastLogin。

第四节构造函数和析构函数

  如果你在一个类中声明一个函数,命名为__construct,这个函数将被当成是一个构造函数并在建立一个对象实例时被执行.清楚地说,__是两个下划线.就像其它任何函数一样,构造函数可能有参数或者默认值.你可以定义一个类来建立一个对象并将其属性全放在一个语句(statement)中.

  你也可以定义一个名为__destruct的函数,PHP将在对象被销毁前调用这个函数.它称为析构函数.

  继承是类的一个强大功能.一个类(子类/派生类)可以继承另一类(父类/基类)的功能.派生类将包含有基类的所有属性和方法,并可以在派生类中加上其他属性和方法.你也可以覆写基类的方法和属性.就像3.1.2中显示的,你可以用extends关键字来继承一个类.

你可能想知道构造函数是如何被继承的.当它们和其它方法一起被继承时,他们不会在创建对象时被执行.如果你需要这个功能,你需要用第二章提到的:

:

运算符.它允许你指向一块命名空间.parent指向父类命名空间,你可以用parent:

__construct来调用父类的构造函数.

一些面向对象语言在类之后命名构造函数.PHP的前几个版本也是如此,到现在这种方法仍然有效.也就是:

如果你把一个类命名为Animal并且在其中建立一个命名也是Animal的方法,则这个方法就是构造函数.如果一个类的同时拥有__construt构造函数和与类名相同的函数,PHP将把__construct看作构造函数.这使得用以前的PHP版本所写的类仍然可以使用.但新的脚本(PHP5)应当使用__construct.

PHP的这种新的声明构造函数的方法可以使构造函数有一个独一无二的名称,无论它所在的类的名称是什么.这样你在改变类的名称时,就不需要改变构造函数的名称.

你可能在PHP中给构造函数一个像其它类方法一样的访问方式.访问方式将会影响从一定范围内实例化对象的能力.这允许实现一些固定的设计模式,如Singleton模式.

析构函数,相反于构造函数.PHP调用它们来将一个对象从内存中销毁.默认地,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源.析构函数允许你在使用一个对象之后执行任意代码来清除内存

当PHP决定你的脚本不再与对象相关时,析构函数将被调用.在一个函数的命名空间内,这会发生在函数return的时候.对于全局变量,这发生于脚本结束的时候.如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值.通常将变量赋值勤为NULL或者调用unset.

下面的例子中,计算从类中实例化的对象的个数.Counter类从构造函数开始增值,在析构函数减值.

一旦你定义了一个类,你可以用new来建立一个这个类的实例.类的定义是设计图,实例则是放在装配线上的元件.New需要类的名称,并返回该类的一个实例.如果构造函数需要参数,你应当在new后输入参数.

当你新建了一个实例,内存会被准备来存储所有属性.每个实例有自己独有的一组属性.但方法是由该类的所有实例共享的。

第五节克隆

PHP5中的对象模型通过引用来调用对象,但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本.为了这样的目的,PHP定义了一个特殊的方法,称为__clone.像__construct和__destruct一样,前面有两个下划线.

  默认地,用__clone方法将建立一个与原对象拥有相同属性和方法的对象.如果你想在克隆时改变默认的内容,你要在__clone中覆写(属性或方法).

  克隆的方法可以没有参数,但它同时包含this和that指针(that指向被复制的对象).如果你选择克隆自己,你要小心复制任何你要你的对象包含的信息,从that到this.如果你用__clone来复制.PHP不会执行任何隐性的复制,

  下面显示了一个用系列序数来自动化对象的例子:

第六节访问属性和方法

一个对象实例的属性是变量,就像PHP的其他变量一样.但是你必须使用->

运算符来引用它们.不需要在属性前使用美元符$.例如,6.1中打印User对象的name属性那一行.

  可以联用->

如果一个对象的属性包含了一个对象,你可以使用两个->

运算符来得到内部对象的属性.你甚至可以用双重引用的字符串来放置这些表达式.看6.5中的例子,对象House中的属性room包含了一组Room对象.

  访问方法和访问属性类似.->

运算符用来指向实例的方法.在例子6.1中调用getLastLogin就是.方法执行起来和类外的函数几乎相同.

  如果一个类从另一类中继承而来,父类中的属性和方法将在子类中都有效,即使在子类中没有声明.像以前提到过的,继承是非常强大的.如果你想访问一个继承的属性,你只需要像访问基类自己的属性那样引用即可,使用:

运算符.

 PHP有两个特殊的命名空间:

parent命名空间指向父类,self命名空间指向当前的类.例子6.6中显示了如何用parent命名空间来调用父类中的构造函数.同时也用self来在构造函数中调用另一个类方法.

  第四节中介绍了如何调用函数.对于对象的成员来是这样调用的:

如果你需要在运行时确定变量的名称,你可以用$this->

$Property这样的表达式.如果你想调用方法,可以用$obj->

$method().

  你也可以用->

运算符来返回一个函数的值,这在PHP以前的版本中是不允许的.例如,你可以写一个像这样的表达式:

$obj->

getObject()->

callMethod().这样避免了使用一个中间变量,也有助于实现某些设计模式,如Factory模式。

第七节类的静态成员

   类的静态成员与一般的类成员不同:

静态成员与对象的实例无关,只与类本身有关.他们用来实现类要封装的功能和数据,但不包括特定对象的功能和数据.静态成员包括静态方法和静态属性.

  静态属性包含在类中要封装的数据,可以由所有类的实例共享.实际上,除了属于一个固定的类并限制访问方式外,类的静态属性非常类似于函数的全局变量

  我们在下例中使用了一个静态属性Counter:

$count.它属于Counter类,而不属于任何Counter的实例.你不能用this来引用它,但可以用self或其它有效的命名表达.在例子中,getCount方法返回self:

$count,而不是Counter:

$count.

  静态方法则实现类需要封装的功能,与特定的对象无关.静态方法非常类似于全局函数.静态方法可以完全访问类的属性,也可以由对象的实例来访问,不论访问的限定语是否是什么.

  在6.3例中,getCount是一个普通的方法,用->

来调用.PHP建立一个this变量,尽管方法没有使用到.但是,getCount不属于任何对象.在有些情况下,我们甚至希望在不存在有效的对象时调用它,那么就应该使用静态方法.PHP将不在静态方法内部建立this变量,即使你从一个对象中调用它们.

  例子6.7由6.3改变getCount为静态方法而来.Static关键字不能阻止一个实例用->

运算符来调用getCount,但PHP将不在方法内部建立this变量.如果你使用this->

来调用,将会出错.

  //6.3例指第四节--构造函数和析构函数中的例子(参看前文),通过两个例子的比较,你可以很好掌握

  //static方法与普通方法之间的区别.

  你可以写一个方法通过判断this是否建立来显示是否它被静态地或者非静态地调用.当然,如果你用了static关键字,不管它怎样被调用,这个方法总是静态的.

  你的类也可以定义常量属性,不需要使用publicstatic,只需要用const关键字即可.常量属性总是静态的.它们是类的属性,而不是实例化该类的对象的属性.

Listing6.7Staticmembers

第八节访问方式

  PHP5的访问方式允许限制对类成员的访问.这是在PHP5中新增的功能,但在许多面向对象语言中都早已存在.有了访问方式,才能开发一个可靠的面向对象应用程序,并且构建可重用的面向对象类库.

  像C++和Java一样,PHP有三种访问方式:

public,private和protected.对于一个类成员的访问方式,可以是其中之一.如果你没有指明访问方式,默认地访问方式为public.你也可以为静态成员指明一种访问方式,将访问方式放在static关键字之前(如publicstatic).

  Public成员可以被毫无限制地访问.类外部的任何代码都可以读写public属性.你可以从脚本的任何地方调用一个public方法.在PHP的前几个版本中,所有方法和属性都是public,这让人觉得对象就像是结构精巧的数组.

  Private(私有)成员只在类的内部可见.你不能在一个private属性所在的类方法之外改变或读取它的值.同样地,只有在同一个类中的方法可以调用一个private方法.继承的子类也不能访问父类中的private成员.

  要注意,类中的任何成员和类的实例都可以访问private成员.看例子6.8,equals方法将两个widget进行比较.==运算符比较同一个类的两个对象,但这个例子中每个对象实例都有唯一的ID.equals方法只比较name和price.注意equals方法如何访问另一个Widget实例的private属性.Java和C都允许这样的操作.

  Listing6.8Privatemembers

  一个子类可能改变通过覆写父类方法来改变方法的访问方式,尽管如此,仍然有一些限制.如果你覆写了一个public类成员,他子类中必须保持public.如果你覆写了一个protected成员,它可保持protected或变成public.Private成员仍然只在当前类中可见.声明一个与父类的private成员同名的成员将简单地在当前类中建立一个与原来不同的成员.因此,在技术上你不能覆写一个private成员.

  Final关键字是限制访问成员方法的另一个方法.子类不能覆写父类中标识为final的方法.Final关键字不能用于属性.

PHP5的面向对象模型仍然不够完善,如final不像Java中那样对Data,Method甚至Class都可以用。

第九节绑定

  除了限制访问,访问方式也决定哪个方法将被子类调用或哪个属性将被子类访问.函数调用与函数本身的关联,以及成员访问与变量内存地址间的关系,称为绑定.

  在计算机语言中有两种主要的绑定方式—静态绑定和动态绑定.静态绑定发生于数据结构和数据结构间,程序执行之前.静态绑定发生于编译期,因此不能利用任何运行期的信息.它针对函数调用与函数的主体,或变量与内存中的区块.因为PHP是一种动态语言,它不使用静态绑定.但是可以模拟静态绑定.

  动态绑定则针对运行期产生的访问请求,只用到运行期的可用信息.在面向对象的代码中,动态绑定意味着决定哪个方法被调用或哪个属性被访问,将基于这个类本身而不基于访问范围.

  Public和protected成员的动作类似于PHP的前几个版本中函数的动作,使用动态绑定.这意味着如果一个方法访问一个在子类中被覆写的类成员,并是一个子类的实例,子类的成员将被访问(而不是访问父类中的成员).

  看例子6.10.这段代码输出”Hey!

IamSon.”因为当PHP调用getSalutation,是一个Son的实例,是将Father中的salutation覆写而来.如果salutation是public的,PHP将产生相同的结果.覆写方法的操作很类似.在Son中,对于identify的调用绑定到那个方法.

  即使在子类中访问方式被从protected削弱成public,动态绑定仍然会发生.按照访问方式使用的原则,增强对于类成员的访问限制是不可能的.所以把访问方式从public改变成protected不可能进行.

  Listing6.10Dynamicbinding动态绑定

//注:

在子类中没有覆写getSalutation(),但实际上仍然存在一个getSalutation().这个类中的$salutation和identify()

//与Son子类的实例中的getSalutation()方法动态绑定,所以调用Son的实例的getSalutation()方法,

//将调用Son类中的成员salutation及identify(),而不是父类中的成员salutation及identify().

  Private成员只存在于它们所在的类内部.不像public和protected成员那样,PHP模拟静态绑定.看例子6.11.它输出”Hellothere!

IamFather.”,尽管子类覆写了salutation的值.脚本将this->

salutation和当前类Father绑定.类似的原则应用于private方法identify().

  Listing6.11Bindingandprivatemembers

  动态绑定的好处是允许继承类来改变父类的行为,同时可以保持父类的接口和功能.看例子6.12.由于使用了动态绑定,在deleteUser中被调用的isAuthorized的version可以由对象的类型来确定.如果是一个普通的user,PHP调用User:

isAuthorized会返回FALSE.如果是一个AuthorizedUser的实例,PHP调用AuthorizedUser:

isAuthorized,将允许deleteUser顺利执行.

用一句话说清楚,就是对象类型与方法,属性绑定.调用一个父类与子类中都存在的方法或访问一个属性时,会先判断实例属于哪种对象类型,再调用相应的类中的方法和属性.

  Listing6.12动态绑定的好处

  为什么private的类成员模拟静态绑定?

为了回答这个问题,你需要回忆一下为什么需要有private成员.什么时候用它们来代替protected成员是有意义的?

  private成员只有当你不想让子类继承改变或特殊化父类的行为时才用到.这种情况比你想像的要少.通常来说,一个好的对象分层结构应当允许绝大多数功能被子类特殊化,改进,或改变—这是面向对象编程的基础之一.一定的情况下需要private方法或变量,例如当你确信你不想允许子类改变父类中的某个特定的部份.

第十节抽象方法和抽象类

  面向对象程序通过类的分层结构构建起来.在单重继承语言如PHP中,类的继承是树状的.一个根类有一个或更多的子类,再从每个子类继承出一个或更多下一级子类.当然,可能存在多个根类,用来实现不同的功能.在一个良好设计的体系中,每个根类都应该有一个有用的接口,可以被应用代码所使用.如果我们的应用代码被设计成与根类一起工作,那么它也可以和任何一个从根类继承出来的子类合作.

  抽象方法是就像子类中一般的方法的占位符(占个地方但不起作用),它与一般方法不同—没有任何代码.如果类中存在一个或更多抽象方法,那么这个类就成了抽象类.你不能实例化抽象类.你必须继承它们,然后实例化子类.你也可以把抽象类看成是子类的一个模板.

  如果你覆写所有的抽象方法,子类就变成一个普通的类.如果没有覆写所有方法,子类仍是抽象的.如果一个类中中包含有抽象方法(哪怕只有一个),你必须声明这个类是抽象的,在class关键字前加上abstract.

  声明抽象方法的语法与声明一般方法不同.抽象方法的没有像一般方法那样包含在大括号{}中的主体部份,并用分号;

来结束.

  在例子6.13中,我们定义了一个含有getArea方法的类Shape.但由于不知道形状不可能确定图形的面积,确良我们声明了getArea方法为抽象方法.你不能实例化一个Shape对象,但你可以继承它或在一个表达式中使用它,就像例6.13中那样.

  如果你建立了一个只有抽象方法的类,你就定义了一个接口(interface).为了说明这种情况,PHP中有interface和implements关键字.你可以用interface来代替抽象类,用implements来代替extends来说明你的类定义或使用一

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 节日庆典

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1