PHP中的类
用php以來,一直懷念java的類和對象,終于PHP 5 引入了新的對象模型(Object Model)。完全重寫了 PHP 處理對象的方式,向java靠齊了。下面來了解下吧!
?
一、定義類和實例化對象
php以關(guān)鍵字class來定義類,使用new來創(chuàng)建一個對象的實例,這就不用多說了。
?
二、自動加載對象機制
以前,我們引用對象,都要在前面使用include或者require將類包含進來,有時一個頁面引用的類多了,感覺很麻煩,php5種,不再需要這樣了,我們可以定義一個__autoload函數(shù),它會在試圖使用尚未被定義的類時自動調(diào)用。這就省得我們在每個頁面都要使用一堆的包含函數(shù)了。
?
使用實例:
類文件:/class/class.testOne.php
<?phpclass testOne{function __construct(){echo "begin";}function __destruct() {}}?>類文件:/class/class.testTwo.php
<?phpclass testTwo{protected $name;function __construct(){echo "conn";}function setName( $name ){$this->name = $name;}function getName(){return "My name is:".$this->name;}function __destruct() {}}?>?
文件:/comm.config.php
<?phpfunction __autoload( $class_name) {require_once "./class/class.".$class_name.'.php';}?>?
文件:/index.php
<?phprequire_once( "comm.config.php" );$testOne = new testOne();?>輸出結(jié)果:begin
?
文件:/index2.php
<?phprequire_once( "comm.config.php" );$testTwo = new testTwo();$testTwo->setName( "test" );echo $testTwo->getName();?>輸出結(jié)果:connMy name is:test
?
?
三、構(gòu)造函數(shù)和析構(gòu)函數(shù)
構(gòu)造函數(shù):void __construct ( [mixed args [, ...]] )
具有構(gòu)造函數(shù)的類會在每次創(chuàng)建對象時先調(diào)用此方法,我們可以在這里做一些初始化操作。
?
析構(gòu)函數(shù):void __destruct ( void )
PHP 5 引入了析構(gòu)函數(shù)的概念,這類似于其它面向?qū)ο蟮恼Z言,如 C++。析構(gòu)函數(shù)會在到某個對象的所有引用都被刪除或者當對象被顯式銷毀時執(zhí)行。
?
注意:
在繼承父類的子類中,默認子類是不會實現(xiàn)父類的構(gòu)造函數(shù)和析構(gòu)函數(shù),要執(zhí)行父類的構(gòu)造函數(shù)和析構(gòu)函數(shù),我們可以使用parent關(guān)鍵字在子類的構(gòu)造函數(shù)和析構(gòu)函數(shù)體中顯式調(diào)用parent::__construct()和parent::__destruct()。
?
四、屬性和方法的可見性
在php5中,我們可以像java一樣,使用public、private、protected關(guān)鍵字來定義屬性或者方法的可見性范圍。
public:聲明方法和屬性可以被隨意訪問。
Protected:聲明的方法和屬性只能被類本身和其繼承子類訪問。
private:只能被定義屬性和方法的類訪問。
?
?
實例:
文件:class.testOne.php
<?phpclass testOne{public $public = "testOne.public";protected $protected = "testOne.preteced";private $private = "testOne.private";function __construct(){}public function getPublic(){return "From testOne.getPublic:".$this->public;}//endprotected function ?getProtected(){return "From testOne.getProtected:".$this->protected;}private function getPrivate(){return "From testOne.getPrivate:".$this->private;}function printAll(){echo $this->public.BR;echo $this->getPublic().BR;echo $this->protected.BR;echo $this->getProtected().BR;echo $this->private.BR;echo $this->getPrivate().BR;}function __destruct() {}}?>?
文件:index.php
<?phprequire_once( "class.testOne.php" );$testOne = new testOne();### ? ?屬性echo $testOne->public.BR;echo $testOne->protected.BR; ? ? //Fatal error: Cannot access protected property testOne::$protected in E:\www3\test\index.php on line 6echo $testOne->private.BR; ? ?//Fatal error: Cannot access private property testOne::$private in E:\www3\test\index.php on line 7### ? ?方法echo $testOne->getPublic().BR;echo $testOne->getProtected().BR;//Fatal error: Call to protected method testOne::getProtected() from context '' in E:\www3\test\index.php on line 10echo $testOne->getPrivate().BR;//Fatal error: Call to private method testOne::getPrivate() from context '' in E:\www3\test\index.php on line 11### ? ?內(nèi)部訪問$testOne->printAll();echo "-----------------".BR;### ? ?定義擴展類class SunClass extends testOne{protected $protected = 'SunClass.protected';function printAll(){echo $this->public.BR;echo $this->getPublic().BR;echo $this->protected.BR;echo $this->getProtected().BR;echo $this->private.BR;//這里不報錯,但是值是空的echo $this->getPrivate().BR;//Fatal error: Call to private method testOne::getPrivate() from context 'SunClass' in E:\www3\test\index.php on line 25}}### ? ?子類訪問$obj2 = new SunClass();$obj2->printAll();?>正常無錯誤的輸出如下:testOne.publicFrom testOne.getPublic:testOne.publictestOne.publicFrom testOne.getPublic:testOne.publictestOne.pretecedFrom testOne.getProtected:testOne.pretecedtestOne.privateFrom testOne.getPrivate:testOne.private-----------------testOne.publicFrom testOne.getPublic:testOne.publicSunClass.protectedFrom testOne.getProtected:SunClass.protected以上實例說名:public或者默認無聲明的屬性和方法無論怎么樣都可以被訪問到。protected的屬性和方法只能在類內(nèi)部或者繼承子類內(nèi)部訪問。private的屬性和方法只能在類自身內(nèi)部訪問。?
?
五、static關(guān)鍵字
將一個類的屬性或者方法定義為static,則可以在不實例化類的情況下使用類的屬性和方法。
?
注意:
1、static關(guān)鍵字必須在public、protected、private之后聲明。
2、子類不能重新定義父類中static關(guān)鍵字修飾的變量屬性或者方法,除非你將它們定義為static成員。
3、static方法或者變量中,$this 變量是不可用的,如果你要使用同一類中其他的定義為static變量或者方法,可以使用self::(變量名|方法名)來訪問static成員。
4、Static成員屬性不能以$object->(static成員屬性)方式訪問,你可以$類名::(static成員屬性)訪問它們。這里跟java不同,PHP中static成員是不能被類的實例對象訪問的。
?
實例:
<?phprequire_once( "comm.config.php" );class Foo{public static $my_static = 'foo';public function staticValue() {###echo $this->$my_static; ? ?//(不能使用$this變量訪問static成員)Fatal error: Cannot access empty property in E:\www3\test\index.php on line 8return self::$my_static;}}class Bar extends Foo{###public static $my_static;//Fatal error: Cannot redeclare static Foo::$my_static as non static Bar::$my_static in E:\www3\test\index.php on line 20(在public后面加上static關(guān)鍵字就ok了)public function fooStatic() {return self::$my_static;}}$foo = new Foo();print $foo->staticValue() . "\n";print Foo::$my_static . "\n";print $foo->my_static . "\n"; ? ? ?// my_static屬性是空的。echo "<br>";// $foo::my_static is not possibleprint Bar::$my_static. "\n";print Bar::staticValue(). "\n";$bar = new Bar();print $bar->fooStatic() . "\n";?>正確的輸出結(jié)果:
foo foo
foo foo foo
?
?
六、作用域分辨運算符(::)
在沒有聲明任何實例的情況下使用::來訪問類中的函數(shù)或者基類中的函數(shù)和變量。
一般用在以下三種情況
1、從類外部不經(jīng)過實例化訪問類成員(比如static或者常量),
使用格式:類名::成名名;
2、類內(nèi)部使用,通過關(guān)鍵字self和parent來實現(xiàn)類內(nèi)部訪問類定義的成員.
3、子類通過關(guān)鍵字parent來訪問父類成員。
?
實例:
class FatherClass{const CONST_VALUE = 'FatherClass.const';static $static = "FatherClass.static";private function goPrivate(){echo "FatherClass.goPrivate<br>";}protected function goProtected() {echo "FatherClass.goProtected<br>";}function goPublic() {echo "FatherClass.goPublic<br>";self::goPrivate();//self關(guān)鍵字訪問內(nèi)部私有方法self::goProtected();//self關(guān)鍵字訪問內(nèi)部保護方法echo self::CONST_VALUE."<br>";//self訪問類內(nèi)部常量echo self::$static."<br>";//self訪問類內(nèi)部static變量}}class SunClass extends FatherClass{function goPrivate(){echo "重載父類方法:SunClass.goPrivate<br>";###parent::goPrivate();//Fatal errorparent::goProtected(); ? ?//parent訪問父類protected方法echo parent::CONST_VALUE."<br>";//parent訪問父類常量echo parent::$static."<br>";//parent訪問父類static變量}}###FatherClass::goPrivate();//這里會出現(xiàn)Fatal error:,因為private修飾的成員外部是不能訪問的。
###FatherClass::goProtected();//這里會出現(xiàn)Fatal error:,因為protected修飾的成員外部是不能直接訪問的,只有子類或者類本身才能訪問。
echo FatherClass::CONST_VALUE."<br>";//通過::訪問到類內(nèi)部常量
echo FatherClass::$static."<br>";//訪問類的static變量
FatherClass::goPublic();//訪問類成員方法
$sunclass = new SunClass();
$sunclass->goPrivate();
?
輸出結(jié)果:
FatherClass.const
FatherClass.static
FatherClass.goPublic
FatherClass.goPrivate
FatherClass.goProtected
FatherClass.const
FatherClass.static
重載父類方法:SunClass.goPrivate
FatherClass.goProtected
FatherClass.const
FatherClass.static
?
七、類常量
我們可以通過定義類常量使得類的每個實例化對象中,成員的值都是相同的,而且對象不能改變它的值。
常量和其他變量的區(qū)別主要在于:
1.類的實例化對象是不能改變常量的值,并且每個實例化對象的常量值都是相同的。
2.不需要$符號來聲明和使用常量。
3.常量不能被類的實例化對象直接使用,它只能在類內(nèi)部使用。這點跟static成員是一相同的。
?
實例:
class MyClass{const constant = 'constant value';function showConstant() {//self::constant = "change constant value"; ###會出現(xiàn)錯誤echo ?self::constant . "\n";}}echo MyClass::constant . "\n";$class = new MyClass();$class->showConstant();//echo $class::constant; ?###is not allowed?
?
八、抽象類
PHP5中引入了abstract類和方法的概念。一個類被聲明為abstract,則此類是不能被實例化的。
如果在一個類內(nèi)部有一個成員方法被聲明成abstract,則這個類也必須是抽象類。
而且抽象成員方法只能定義方法的名稱,不能定義方法的實現(xiàn)細節(jié),這些方法的實現(xiàn)細節(jié)是留待繼承
此抽象類的子類去實現(xiàn)的。子類繼承抽象類時,除非子類仍然聲明為抽象類,否則就必須實現(xiàn)抽象類中
所有聲明為abstract的成員方法。注意,子類在是實現(xiàn)抽象類的抽象成員時,子類成員的可見性必須
和抽象類保持一致或者小于抽象類的成員可見性。
比如:抽象方法定義為protected,則實現(xiàn)此抽象方法的子類必須聲明為protected或者public,而不能聲明為private。
?
實例:
//class AbstractClass ###如果去掉abstract關(guān)鍵字將出現(xiàn)錯誤
abstract class AbstractClass{// Force Extending class to define this methodabstract protected function getValue();abstract protected function prefixValue($prefix);// Common methodpublic function printOut() {print $this->getValue() . "\n";}}class ConcreteClass1 extends AbstractClass{//private function getValue(){ ###如果聲明為private 會出現(xiàn)錯誤public function getValue() {return "ConcreteClass1";}public function prefixValue($prefix) {return "{$prefix}ConcreteClass1";}}//$class = new AbstractClass();###出現(xiàn)錯誤,抽象類不能被實例化$class1 = new ConcreteClass1;$class1->printOut();echo $class1->prefixValue('FOO_') ."\n";?
九、接口
接口允許你創(chuàng)建一個只有方法聲明,而無具體實現(xiàn)的類對象.接口是一系列方法的聲明,是一些方法特征的集合,
一個接口只有方法的特征沒有方法的實現(xiàn),因此這些方法可以在不同的地方被不同的類實現(xiàn),
而這些實現(xiàn)可以具有不同的行為(函數(shù))。 接口把方法的特征和方法的實現(xiàn)分割開來。這種分割體現(xiàn)在接口常常代表一個角色,
它包裝與該角色相關(guān)的操作和屬性,而實現(xiàn)這個接口的類便是扮演這個角色的演員。一個角色由不同的演員來演,而不同的演員之間除了扮演一個共同的角色之外,
并不要求其它的共同之處。
?
注:
1、接口由interface關(guān)鍵字聲明。
2、接口的所有方法作用域必須是public的。
3、接口只定義方法,沒有任何有實際意義的代碼,具體的代碼由實現(xiàn)這個接口的類來完成。
4、實現(xiàn)類通過implements來實現(xiàn)接口,接口所定義的方法,實現(xiàn)類必須全部實現(xiàn)。
5、實現(xiàn)類可以實現(xiàn)多個接口,只需要將接口用逗號隔開即可。
6、對象是對某類的事物的抽象,接口是對對象的抽象,接口用來標志類的類別。
7、接口是不能實例化的。
?
實例:
// 聲明接口'iFaceOne'interface iFaceOne{public function setVariable($name, $var);public function ? ?getVariable( $name );}// 聲明接口'iFaceTwo'interface iFaceTwo{public function getHtml( $str );}//聲明接口'iFaceTwoSun'繼承iFaceTwo接口,擴展setHtml方法interface iFaceTwoSun extends iFaceTwo{public function setHtml();}//類one實現(xiàn)iFaceOne、iFaceTwo接口class one implements iFaceOne,iFaceTwo{private $test = "";//實現(xiàn)iFaceOne接口的setVariable方法public function setVariable( $name,$var ){echo "one實現(xiàn)iFaceOne.setVariable<BR>";$this->$name = $var;}//實現(xiàn)iFaceOne接口的getVariable方法public function getVariable( $name ){echo "one實現(xiàn)iFaceOne.getVariable<BR>";return $this->$name;}//實現(xiàn)iFaceTwo接口的getHtml方法public function getHtml( $str ){echo "one實現(xiàn)iFaceTwo.getHtml<BR>";return $str;}}//類two實現(xiàn)iFaceTwo接口class two implements iFaceTwoSun{public function getHtml( $str ){echo "two實現(xiàn)iFaceTwo.getHtml<BR>";return $str;}public function setHtml(){echo "two實現(xiàn)iFaceTwoSun.getHtml<BR>";}}class three{function get(iFaceTwo $Obj,$str ){return $Obj->getHtml( $str );}function set( iFaceTwo $Obj ){return $Obj->setHtml();}}$three = new three();$one = new one();$two = new two();//$iFaceOne = new iFaceOne(); ? ?//報錯,因為接口是不能被實例化的$one->setVariable( "test","one" );$rs = $one->getVariable( "test" );echo $rs."<hr>";$rs = $two->getHtml( "two" );echo $rs."<br>";$rs = $two->setHtml();echo "<hr>";$rs = $three->get( $one,"one" );echo $rs."<hr>";$rs = $three->set( $two,"two" );echo $rs."<hr>";//$three->setHTML( $one );//報錯$three->set( $two )?
總結(jié)
- 上一篇: PHP实现图片马赛克效果
- 下一篇: PHP中echo与print和print