PHP面向对象教程.docx
《PHP面向对象教程.docx》由会员分享,可在线阅读,更多相关《PHP面向对象教程.docx(51页珍藏版)》请在冰点文库上搜索。
![PHP面向对象教程.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/e2259cba-3eab-4a8f-b4a6-2f91182ac2a0/e2259cba-3eab-4a8f-b4a6-2f91182ac2a01.gif)
PHP面向对象教程
PHP面向对象、类经典教程
PHP面向对象、类经典教程这是一篇很详细的介绍PHP面向对象的教程,转载下载希望对你和你的朋友学习PHP有所帮助!
谢谢您对本站的支持!
:
)
由于php手册从这一章节开始没有翻译,都是英文,近来自己开始学习php5中的面向对象编程,为方便学习和阅读,所以把其翻译之,发上来与大家分享,有不妥之处请大家批评指正!
对属性或方法的访问控制,是通过在前面添加关键字public、protected或private来实现的。
由public所定义的类成员可以在任何地方被访问;由protected所定义的类成员则可以被其所在类的子类和父类访问(当然,该成员所在的类也可以访问);而由private定义的类成员则只能被其所在类访问。
对类成员的访问控制
类成员都必须使用关键字public、protected或private进行定义
例10.9.声明类成员
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;////Works
echo$obj->protected;//FatalError
echo$obj->private;//FatalError
$obj->printHello();//ShowsPublic,ProtectedandPriv
classMyClass2extendsMyClass //DefineMyClass2
{//Wecanredeclarethepublicandprotectedmethod,butnotprivate
protected$protected='Protected2';
functionprintHello()
{ echo$this->public;
echo$this->protected;
echo$this->private;
}
}
$obj2=newMyClass2();
echo$obj->public;//Works
echo$obj2->private;//Undefined
echo$obj2->protected;//FatalError
$obj2->printHello();//ShowsPublic,Protected2,notPrivate
?
>
注意:
在PHP4中使用var关键字对变量进行定义的方法在PHP5的面向对象语法中不再使用。
为了顾及兼容性,在类中定义一个变量的话,该变量会被自动设为public,并且产生一个E_STRICT警告。
对方法的访问控制
类中的方法都必须使用关键字public、protected或private进行定义。
如果没有设置这些关键字,则该方法会被设置成默认的public。
例10.10.声明类中的方法
php
classMyClass //DefineMyClass
{ publicfunction__construct(){}
publicfunctionMyPublic(){}
protectedfunctionMyProtected(){}
privatefunctionMyPrivate(){}
functionFoo()
{ $this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass=newMyClass;
$myclass->MyPublic();//
$myclass->MyProtected();//
$myclass->MyPrivate();//
$myclass->Foo();
classMyClass2extendsMyClass //DefineMyClass2
{ //Thisispublic
functionFoo2()
{ $this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass2=newMyClass2;
$myclass2->MyPublic();
$myclass2->Foo2();
?
>
第19章类与对象(PHP5)之二:
范围解析操作符(:
:
)--ScopeResolutionOperator(:
:
)
范围解析操作符(也可称作PaamayimNekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员、方法和常量,还可以用于覆盖类中的成员和方法。
当在类的外部访问这些静态成员、方法和常量时,必须使用类的名字。
把PaamayimNekudotayim选作该操作符的名字似乎有些奇怪。
然而,这是Zend开发小组在写ZendEngine0.5(被用于PHP3中)时所作出的决定。
事实上这个词在希伯莱文就是双冒号的意思。
例10.11.在类的外部使用:
:
操作符
php
classMyClass
{ constCONST_VALUE='Aconstantvalue';
}
echoMyClass:
:
CONST_VALUE;
?
>
self和parent这两个特殊的关键字是用于在类的内部对成员或方法进行访问的。
例10.12.:
:
frominsidetheclassdefinition
php
classOtherClassextendsMyClass
{ publicstatic$my_static='staticvar';
publicstaticfunctiondoubleColon()
{ echoparent:
:
CONST_VALUE."\n";
echoself:
:
$my_static."\n";
}
}
OtherClass:
:
doubleColon();
?
>
当一个子类覆盖其父类中的方法时,PHP不会再执行父类中已被覆盖的方法,直到子类中调用这些方法为止。
这种机制也作用于构造函数和析构函数、重载及魔术函数。
例10.13.调用父类的方法
php
classMyClass
{ protectedfunctionmyFunc(){ echo"MyClass:
:
myFunc()\n"; }
}
classOtherClassextendsMyClass
{ //Overrideparent'sdefinition
publicfunctionmyFunc()
{ //Butstillcalltheparentfunction
parent:
:
myFunc();
echo"OtherClass:
:
myFunc()\n";
}
}
$class=newOtherClass();
$class->myFunc();
?
>
第19章类与对象(PHP5)之三:
静态关键字(StaticKeyword)
声明静态的类的成员和方法,使它不需要一个类的实例.一个static成员的声明不能通过一个类对象的实例来访问(尽管一个静态方法可以)。
静态声明必须在可见性声明之后。
为了兼容PHP4,如果没有可见性被声明,那么成员和方法将被当作是已经声明为public。
由于静态方法可以调用非对象实例,伪变量$this不可以在声明为静态的方法中使用。
事实上static方法调用形式在编译时被确定。
当使用必须要声明的类名时,方法是完全标识和无继承规则的应用。
当使用必须要声明的类名时,这种方法就被完全确认,而且没有使用继承的规则。
如果self已经被声明,那么self就被当前所属的类所解释。
也不适用与继承规则。
静态属性不能通过箭头操作符->.访问非静态方法,这将产生一个E_STRICT级的警告。
例子19-13.静态成员的例子
php
classFoo
{ publicstatic$my_static='foo';
publicfunctionstaticValue(){ returnself:
:
$my_static; }
}
classBarextendsFoo
{ publicfunctionfooStatic(){ returnparent:
:
$my_static; }
}
printFoo:
:
$my_static."\n";
$foo=newFoo();
print$foo->staticValue()."\n";
print$foo->my_static."\n";//Undefined"Property"my_static
//$foo:
:
my_staticisnotpossible
printBar:
:
$my_static."\n";
$bar=newBar();
print$bar->fooStatic()."\n";
?
>
例子19-14.静态方法实例(Staticmethodexample)
php
classFoo
{ publicstaticfunctionaStaticMethod(){ }
}
Foo:
:
aStaticMethod();
?
>
第19章类与对象(PHP5)之四:
类常量(ClassConstants)
可以在每个基类中定义常量使它保持不变。
在你不使用$符号去声明或使用它时,常量不同于普通变量。
就象静态成员,常量值不能通过对象的实例来访问(而应使用$object:
:
constant).常量值必须是一个常量表达式,而不是一个变量,一个类的成员,一个数学表达式或函数调用的结果。
例子19-15.定义并使用一个常量
php
classMyClass
{ constconstant='constantvalue';
functionshowConstant(){ echo self:
:
constant."\n"; }
}
echoMyClass:
:
constant."\n";
$class=newMyClass();
$class->showConstant();//echo$class:
:
constant;isnotallowed
?
>
第19章类与对象(PHP5)之五:
抽象类(ClassAbstraction)
PHP5中引入了抽象类和抽象方法。
不允许创建一个已经定义为abstract的类的一个实例。
任何至少包含一个抽象方法的类也必须是抽象的。
被定义为抽象的方法仅仅是声明方法的一个信号,并不能定义它们的实现。
当从一个抽象类继承时,在父类中所有抽象方法的标记的声明必须通过子类定义;另外,这些方法必须用定义相同的访问属性。
例如,如果方法被定义为protected类型,执行函数必须定义为protected或public.
例子19-16.抽象类例子
php
abstractclassAbstractClass
{ //ForceExtendingclasstodefinethismethod
abstractprotectedfunctiongetValue();
abstractprotectedfunctionprefixValue($prefix);
publicfunctionprintOut() //Commonmethod
{
print$this->getValue()."\n";
}
}
classConcreteClass1extendsAbstractClass
{ protectedfunctiongetValue()
{
return"ConcreteClass1";
}
publicfunctionprefixValue($prefix)
{
return"{$prefix}ConcreteClass1";
}
}
classConcreteClass2extendsAbstractClass
{ publicfunctiongetValue()
{
return"ConcreteClass2";
}
publicfunctionprefixValue($prefix)
{
return"{$prefix}ConcreteClass2";
}
}
$class1=newConcreteClass1;
$class1->printOut();
echo$class1->prefixValue('FOO_')."\n";
$class2=newConcreteClass2;
$class2->printOut();
echo$class2->prefixValue('FOO_')."\n";
?
>
上例将输出:
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
旧代码拥有非用户自定义的命名为abstract的类或函数将要运行如果没有被修改。
第19章类与对象(PHP5)之六:
对象接口(ObjectInterfaces)
对象接口允许你创建一个指定类的方法的执行代码,而不必说明这些方法是如何被操作(处理)的。
接口被用来定义接口关键字的使用,同样作为一个标准类,但没有任何方法有它们内容的定义。
在接口中所有的方法必须声明为public,这是接口的特性。
implements(执行,实现)
为了实现一个接口,使用了implements操作。
在接口中所有的方法必须在一个类的内部实现;疏忽这些将导致一个致命错误。
如果渴望通过使用一个逗号分开每个接口,类可以实现多个接口。
例子19-17.接口实例
php
//Declaretheinterface'iTemplate'
interfaceiTemplate
{ publicfunctionsetVariable($name,$var);
publicfunctiongetHtml($template);
}
//Implementtheinterface.Thiswillwork
classTemplateimplementsiTemplate
{ private$vars=array();
publicfunctionsetVariable($name,$var){ $this->vars[$name]=$var; }
publicfunctiongetHtml($template)
{ foreach($this->varsas$name=>$value)
{ $template=str_replace('{'.$name.'}',$value,$template);
}
return$template;
}
}
//ThiswillnotworkFatalerror:
ClassBadTemplatecontains1abstract
//methosandmustthereforebedeclaredabstract(iTemplate:
:
getHtml)
classBadTemplateimplementsiTemplate
{ private$vars=array();
publicfunctionsetVariable($name,$var){ $this->vars[$name]=$var; }
}
?
>
第19章类与对象(PHP5)之七:
重载(Overloading)
方法调用和成员访问都能通过__call,__get和__set方法被加载。
这些方法将只有当你试图访问不包括成员或方法的对象或继承对象时触发。
不是所有的重载方法都必须被定义为static.
从PHP5.1.0开始也可以通过__isset()和__unset()方法逐个重载isset()和unset()函数。
成员函数重载(Memberoverloading)
void__set(stringname,mixedvalue)
mixed__get(stringname)
bool__isset(stringname)
void__unset(stringname)
类成员可以通过定义这些指定的特定方法加载类中的自定义代码。
$name参数被用来命名变量,这些变量必须是被设置的或返回的。
__set()方法的$value参数指定设置$name的对象的值。
例子19-18.使用__get,__set,__isset和__unset重载的例子
php
classSetter
{ public$n;
private$x=array("a"=>1,"b"=>2,"c"=>3);
privatefunction__get($nm)
{ echo"Getting[$nm]\n";
if(isset($this->x[$nm]))
{ $r=$this->x[$nm];
print"Returning:
$r\n";
return$r;
}else{ echo"Nothing!
\n"; }
}
privatefunction__set($nm,$val)
{ echo"Setting[$nm]to$val\n";
if(isset($this->x[$nm]))
{ $this->x[$nm]=$val;
echo"OK!
\n";
}else{ echo"NotOK!
\n"; }
}
privatefunction__isset($nm)
{ echo"Checkingif$nmisset\n";
returnisset($this->x[$nm]);
}
privatefunction__unset($nm)
{ echo"Unsetting$nm\n";
unset($this->x[$nm]);
}
}
$foo=newSetter();
$foo->n=1;
$foo->a=100;
$foo->a++;
$foo->z++;
var_dump(isset($foo->a));//true
unset($foo->a);
var_dump(isset($foo->a));//false
//thisdoesn'tpassthroughthe__isset()method
because'n'isapublicproperty
var_dump(isset($foo->n));
var_dump($foo);
?
>
上例将输出:
Setting[a]to100
OK!
Getting[a]
Returning:
100
Setting[a]to101
OK!
Getting[z]
Nothing!
Setting[z]to1
NotOK!
Checkingifaisset
bool(true)
Unsettinga
Checkingifaisset
bool(false)
bool(true)
object(Setter)#1
(2){
["n"]=>int
(1)["x:
private"]=>array
(2){
["b"]=>
int
(2)
["c"]=>
int(3)
}
}
例子19-21.迭代器实现对象迭代(ObjectIterationimplementingIterator)
php
classMyIteratorimplementsIterator
{ private$var=array();
publicfunction__construct($array)
{ if(is_array($array)){ $this->var=$array;}
}
publicfunctionrewind()
{ echo"rewinding\n";
reset($this->var);
}
publicfunctioncurrent()
{ $var=current($this->var);
echo"current:
$var\n";
return$var;
}