PHP教程第十一讲.docx
- 文档编号:23493391
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:19
- 大小:20.97KB
PHP教程第十一讲.docx
《PHP教程第十一讲.docx》由会员分享,可在线阅读,更多相关《PHP教程第十一讲.docx(19页珍藏版)》请在冰豆网上搜索。
PHP教程第十一讲
一、基本概念
1.class
每个类的定义都以关键字class开头,后面跟着类名,可以是任何非PHP保留字的名字。
后面跟着一对花括号,里面包含有类成员和方法的定义。
伪变量\$this可以在当一个方法在对象内部调用时使用。
\$this是一个到调用对象(通常是方法所属于的对象,但也可以是另一个对象,如果该方法是从第二个对象内静态调用的话)的引用。
看下面例子:
Example1面向对象语言中的$this变量:
php
classA
{
functionfoo()
{
if(isset($this)){
echo'$thisisdefined(';
echoget_class($this);
echo")\n";
}else{
echo"\$thisisnotdefined.\n";
}
}
}
classB
{
functionbar()
{
A:
:
foo();
}
}
$a=newA();
$a->foo();
A:
:
foo();
$b=newB();
$b->bar();
B:
:
bar();
?
>
以上例程会输出:
$thisisdefined(a)
$thisisnotdefined.
$thisisdefined(b)
$thisisnotdefined.
Example2简单的类定义:
php
classSimpleClass
{
//成员声明
public$var='adefaultvalue';
//方法声明
publicfunctiondisplayVar(){
echo$this->var;
}
}
?
>
Example3类成员的默认值:
php
classSimpleClass
{
//无效的类成员定义:
public$var1='hello'.'world';
public$var2=<< helloworld EOD; public$var3=1+2; public$var4=self: : myStaticMethod(); public$var5=$myVar; //正确的类成员定义: public$var6=myConstant; public$var7=self: : classConstant; public$var8=array(true,false); } ? > 2.new 要创建一个对象的实例,必须创建一个新对象并将其赋给一个变量。 当创建新对象时该对象总是被赋值,除非该对象定义了构造函数并且在出错时抛出了一个异常。 Example4创建一个实例: php $instance=newSimpleClass(); ? > 当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。 此行为和给函数传递入实例时一样。 可以用克隆给一个已创建的对象建立一个新实例。 Example5对象赋值 php $assigned=$instance; $reference=&$instance; $instance->var='$assignedwillhavethisvalue'; $instance=null;//$instanceand$referencebecomenull var_dump($instance); var_dump($reference); var_dump($assigned); ? > 以上例程会输出: NULL NULL object(SimpleClass)#1 (1){ ["var"]=> string(30)"$assignedwillhavethisvalue" } 3.extends 一个类可以在声明中用extends关键字继承另一个类的方法和成员。 PHP不支持多重继承,一个类只能继承一个基类。 被继承的方法和成员可以通过用同样的名字重新声明被覆盖,除非父类定义方法时使用了final关键字。 可以通过parent: : 来访问被覆盖的方法或成员。 简单的类继承: php classExtendClassextendsSimpleClass { //Redefinetheparentmethod functiondisplayVar() { echo"Extendingclass\n"; parent: : displayVar(); } } $extended=newExtendClass(); $extended->displayVar(); ? > 以上例程会输出: Extendingclass adefaultvalue 二、属性 类的变量成员叫做“属性”,或者叫“字段”、“特征”,在本文档统一称为“属性”。 属性声明是由关键字public或者protected或者private开头,然后跟一个变量来组成。 属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指php脚本在编译阶段时就为常数,而不是在编译阶段之后在运行阶段运算出的常数。 在类的成员方法里面,可以通过\$this->property(property是属性名字)这种方式来访问类的属性、方法,但是要访问类的静态属性或者在静态方法里面却不能使用,而是使用self: : $property。 Example1属性声明 php classSimpleClass { //错误的属性声明 public$var1='hello'.'world'; public$var2=<< helloworld EOD; public$var3=1+2; public$var4=self: : myStaticMethod(); public$var5=$myVar; //正确的属性声明 public$var6=myConstant; public$var7=array(true,false); //在php5.3.0及之后,下面的声明也正确 public$var8=<<<'EOD' helloworld EOD; } ? > 跟heredocs不同,nowdocs能够使用在静态变量,也能使用在静态声明。 Example2示例: 使用nowdoc初始化属性 php classfoo{ //AsofPHP5.3.0 public$bar=<<<'EOT' bar EOT; } ? > 三、类常量 我们可以在类中定义常量。 常量的值将始终保持不变。 在定义和使用常量的时候不需要使用$符号。 常量的值必须是一个定值,不能是变量,类属性或其它操作(如函数调用)的结果。 Example1定义和使用一个类常量 php classMyClass { constconstant='constantvalue'; functionshowConstant(){ echoself: : constant."\n"; } } echoMyClass: : constant."\n"; $classname="MyClass"; echo$classname: : constant."\n";//PHP5.3.0之后 $class=newMyClass(); $class->showConstant(); echo$class: : constant."\n";//PHP5.3.0之后 ? > Example2静态数据示例 php classfoo{ //PHP5.3.0之后 constbar=<<<'EOT' bar EOT; } ? > 和heredocs(字符串边界符)不同,nowdocs可以用在任何静态数据中。 四、自动加载对象 在5.3.0版之前,__autoload函数抛出的异常不能被catch语句块捕获并会导致一个致命错误。 从5.3.0+之后,__autoload函数抛出的异常可以被catch语句块捕获,但需要遵循一个条件。 如果抛出的是一个自定义异常,那么必须存在相应的自定义异常类。 __autoload函数可以递归的自动加载自定义异常类。 Note: 如果使用PHP的CLI交互模式时,Autoloading是无效的。 Example1Autoload例子 php function__autoload($class_name){ require_once$class_name.'.php'; } $obj=newMyClass1(); $obj2=newMyClass2(); ? > 五、构造函数和析构函数 1.构造函数 void__construct([mixed、\$args[,\$...]]) PHP5允行开发者在一个类中定义一个方法作为构造函数。 具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。 Note: 如果子类中定义了构造函数则不会隐式调用其父类的构造函数。 要执行父类的构造函数,需要在子类的构造函数中调用parent: : __construct()。 Example1使用新标准的构造函数 php classBaseClass{ function__construct(){ print"InBaseClassconstructor\n"; } } classSubClassextendsBaseClass{ function__construct(){ parent: : __construct(); print"InSubClassconstructor\n"; } } $obj=newBaseClass(); $obj=newSubClass(); ? > 为了实现向后兼容性,如果PHP5在类中找不到__construct()函数,它就会尝试寻找旧式的构造函数,也就是和类同名的函数。 因此唯一会产生兼容性问题的情况是: 类中已有一个名为__construct()的方法,但它却又不是构造函数。 2.析构函数 void__destruct(void)PHP5引入了析构函数的概念,这类似于其它面向对象的语言,如C++。 析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。 Example3析构函数示例 php classMyDestructableClass{ function__construct(){ print"Inconstructor\n"; $this->name="MyDestructableClass"; } function__destruct(){ print"Destroying".$this->name."\n"; } } $obj=newMyDestructableClass(); ? > 和构造函数一样,父类的析构函数不会被引擎暗中调用。 要执行父类的析构函数,必须在子类的析构函数体中显式调用parent: : __destruct()。 析构函数即使在使用exit()终止脚本运行时也会被调用。 在析构函数中调用exit()将会中止其余关闭操作的运行。 六、访问控制 对属性或方法的访问控制,是通过在前面添加关键字public、protected或private来实现的。 由public所定义的类成员可以在任何地方被访问;由protected所定义的类成员则可以被其所在类的子类和父类访问(当然,该成员所在的类也可以访问);而由private定义的类成员则只能被其所在类访问。 1.对类成员的访问控制 类成员都必须使用关键字public、protected或private进行定义,默认为public Example1声明类成员 php /** *DefineMyClass */ classMyClass { public$public='Public'; protected$protected='Protected'; private$private='Private'; functionprintHello() { echo$this->public; echo$this->protected; echo$this->private; } } $obj=newMyClass(); echo$obj->public;//这行能被正常执行 echo$obj->protected;//这行会产生一个致命错误 echo$obj->private;//这行也会产生一个致命错误 $obj->printHello();//输出Public、Protected和Private /** *DefineMyClass2 */ classMyClass2extendsMyClass { //可以对public和protected进行重定义,但private而不能 protected$protected='Protected2'; functionprintHello() { echo$this->public; echo$this->protected; echo$this->private; } } $obj2=newMyClass2(); echo$obj->public;//这行能被正常执行 echo$obj2->private;//未定义private echo$obj2->protected;//这行会产生一个致命错误 $obj2->printHello();//输出Public、Protected2,但不会输出Private classBar { publicfunctiontest(){ $this->testPrivate(); $this->testPublic(); } publicfunctiontestPublic(){ echo"Bar: : testPublic\n"; } privatefunctiontestPrivate(){ echo"Bar: : testPrivate\n"; } } classFooextendsBar { publicfunctiontestPublic(){ echo"Foo: : testPublic\n"; } privatefunctiontestPrivate(){ echo"Foo: : testPrivate\n"; } } $myFoo=newfoo(); $myFoo->test();//Bar: : testPrivate //Foo: : testPublic ? > Note: 为了兼容性考虑,在PHP4中使用var关键字对变量进行定义的方法在PHP5中仍然有效(只是作为public关键字的一个别名)。 在PHP5.1.3之前的版本,该语法会产生一个E_STRICT警告。 2.对方法的访问控制 类中的方法都必须使用关键字public、protected或private进行定义。 如果没有设置这些关键字,则该方法会被设置成默认的public。 Example2声明类中的方法 php /** *DefineMyClass */ classMyClass { //构造函数必须是public publicfunction__construct(){} //声明一个public的方法 publicfunctionMyPublic(){} //声明一个protected的方法 protectedfunctionMyProtected(){} //声明一个private的方法 privatefunctionMyPrivate(){} //这个方法也是public的 functionFoo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); } } $myclass=newMyClass; $myclass->MyPublic();//这行能被正常执行 $myclass->MyProtected();//这行会产生一个致命错误 $myclass->MyPrivate();//这行会产生一个致命错误 $myclass->Foo();//Public、Protected和Private都被调用了 /** *DefineMyClass2 */ classMyClass2extendsMyClass { //Thisispublic functionFoo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate();//这行会产生一个致命错误 } } $myclass2=newMyClass2; $myclass2->MyPublic();//这行能被正常执行 $myclass2->Foo2();//Public和Protected都被调用了,但Private不会被调用 ? > 七、对象继承 继承已为大家所熟知的一个程序设计特性,PHP的对象模型也使用了继承。 继承将会影响到类与类,对象与对象之间的关系。 比如,当扩展一个类,子类就会继承父类的所有公有和保护方法。 但是子类的方法会覆盖父类的方法。 继承对于功能的设计和抽象是非常有用的,而且对于类似的对象增加新功能就无须重新再写这些公用的功能。 Example1继承代码示例 php classfoo { publicfunctionprintItem($string) { echo'Foo: '.$string.PHP_EOL; } publicfunctionprintPHP() { echo'PHPisgreat.'.PHP_EOL; } } classbarextendsfoo { publicfunctionprintItem($string) { echo'Bar: '.$string.PHP_EOL; } } $foo=newfoo(); $bar=newbar(); $foo->printItem('baz');//Output: 'Foo: baz' $foo->printPHP();//Output: 'PHPisgreat' $bar->printItem('baz');//Output: 'Bar: baz' $bar->printPHP();//Output: 'PHPisgreat' ? > 八、范围解析操作符(: : ) 范围解析操作符(也可称作PaamayimNekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员、方法和常量,还可以用于覆盖类中的成员和方法。 当在类的外部访问这些静态成员、方法和常量时,必须使用类的名字。 把PaamayimNekudotayim选作该操作符的名字似乎有些奇怪。 然而,这是Zend开发小组在写ZendEngine0.5(被用于PHP3中)时所作出的决定。 事实上这个词在希伯莱文就是双冒号的意思。 Example1在类的外部使用: : 操作符 php classMyClass{ constCONST_VALUE='Aconstantvalue'; } echoMyClass: : CONST_VALUE; ? > self和parent这两个特殊的关键字是用于在类的内部对成员或方法进行访问的。 Example#2: : frominsidetheclassdefinition php classOtherClassextendsMyClass { publicstatic$my_static='staticvar'; publicstaticfunctiondoubleColon(){ echoparent: : CONST_VALUE."\n"; echoself: : $my_static."\n"; } } OtherClass: : doubleColon(); ? > 当一个子类覆盖其父类中的方法时,PHP不会再执行父类中已被覆盖的方法,直到子类中调用这些方法为止。 这种机制也作用于构造函数和析构函数、重载及魔术函数。 Example3调用父类的方法 php classMyClass { protectedfunctionmyFunc(){ echo"MyClass: : myFunc()\n"; } } classOtherClassextendsMyClass { //覆盖父类中的方法 publicfunctionmyFunc() { //但仍然可以调用已被覆盖的方法 parent: : myFunc(); echo"OtherClass: : myFunc()\n"; } } $class=newOtherClass(); $class->myFunc(); ? > 九、小结 PHP中用class来定义类,用new实例化对象,用extends继承类,不过只能单继承,属性和方法有public、private和protected做访问控制,默认为public,在类里定义常量不需要\$,用: : 范围解析符可以调用父类的方法,访问类的静态变量、静态方法和常量。 十、练习 请定义一个动物类,然后定义一个小狗类继承动物类,里面定义一个吠叫的方法,最后实例化一条小狗,调用它吠叫的方法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PHP 教程 第十一