一個類可以包含有屬于自己的常量,變量(稱為“屬性”)以及函數(shù)(稱為“方法”)。當(dāng)一個方法在類定義內(nèi)部被調(diào)用時,有一個可用的偽變量 $this。$this 是一個到主叫對象的引用,通常是該方法所從屬的對象。
一個類可以在聲明中用 extends 關(guān)鍵字繼承另一個類的方法和屬性。PHP不支持多重繼承,一個類只能繼承一個基類。
被繼承的方法和屬性可以通過用同樣的名字重新聲明被覆蓋。但是如果父類定義方法時使用了 final,則該方法不可被覆蓋。可以通過 parent:: 來訪問被覆蓋的方法或?qū)傩浴?br>
當(dāng)覆蓋方法時,參數(shù)必須保持一致否則 PHP 將發(fā)出 E_STRICT 級別的錯誤信息。但構(gòu)造函數(shù)例外,構(gòu)造函數(shù)可在被覆蓋時使用不同的參數(shù)。
引用和賦值
對象擁有很多的屬性和方法,這些基本類型的數(shù)據(jù)在自己的坑好好呆著,一個對象的句柄也作為一種基本類型在一個坑呆著。當(dāng)$objectVar的引用賦給$reference時,這兩個對象的句柄都指向同一個坑,它們的foo也是指向同一個坑,但是把$objectVar作為一個變量賦給$assignment時,它們的handle指向同一個坑,但是這個時候坑的引用計數(shù)變成2。
self 和 $this 區(qū)別:self指的是當(dāng)前類,$this指當(dāng)前對象
stdClass: 是php的默認(rèn)對象,不包含任何屬性、方法,不支持魔術(shù)方法,不實現(xiàn)任何接口,它不是基本類型。
類的常量
常量的值必須是一個定值,不能是變量,類屬性,數(shù)學(xué)運算的結(jié)果或函數(shù)調(diào)用。
在父類定義了常量,在子類可以被覆蓋。
需要注意的:在類中定義了一個常量,用self::$name和static::$name都獲取不到,前一個是undefined,后一個是null。只能用類名獲取。
自動加載類
可以定義一個 __autoload() 函數(shù),它會在試圖使用尚未被定義的類時自動調(diào)用。
spl_autoload_register方法:定義一個方法load加載某個文件,spl_autoload_register(‘load’),表示在遇到?jīng)]有定義的類的時候就執(zhí)行l(wèi)oad方法自動加載。
spl_autoload_register( array('test','loadprint') );表示加載test類的loadprint方法
構(gòu)造函數(shù)和析構(gòu)函數(shù)
如果子類中定義了構(gòu)造函數(shù)則不會隱式調(diào)用其父類的構(gòu)造函數(shù)。要執(zhí)行父類的構(gòu)造函數(shù),需要在子類的構(gòu)造函數(shù)中調(diào)用 parent::__construct()。如果子類沒有定義構(gòu)造函數(shù)則會如同一個普通的類方法一樣從父類繼承(假如沒有被定義為 private 的話)。
和構(gòu)造函數(shù)一樣,父類的析構(gòu)函數(shù)不會被引擎暗中調(diào)用。要執(zhí)行父類的析構(gòu)函數(shù),必須在子類的析構(gòu)函數(shù)體中顯式調(diào)用 parent::__destruct()。此外也和構(gòu)造函數(shù)一樣,子類如果自己沒有定義析構(gòu)函數(shù)則會繼承父類的。
析構(gòu)函數(shù)即使在使用 exit() 終止腳本運行時也會被調(diào)用。在析構(gòu)函數(shù)中調(diào)用 exit() 將會中止其余關(guān)閉操作的運行。
訪問控制
屬性:public,var供有,private,私有,protected 受保護(hù)
方法:不寫任何定義,則默認(rèn)共有。
同一個類的對象即使不是同一個實例也可以互相訪問對方的私有與受保護(hù)成員。這是由于在這些對象的內(nèi)部具體實現(xiàn)的細(xì)節(jié)都是已知的。
如果一個類被定義成abstract,它就必須被繼承,不能直接使用。
靜態(tài)常量
static類型的屬性在子類定義,父類可以訪問。self和static:self指的是當(dāng)前類的,就是代碼所在的那個類,static指定的調(diào)用它的類。
抽象類
定義為抽象的類不能被實例化。任何一個類,如果它里面至少有一個方法是被聲明為抽象的,那么這個類就必須被聲明為抽象的。被定義為抽象的方法只是聲明了其調(diào)用方式(參數(shù)),不能定義其具體的功能實現(xiàn)。
繼承一個抽象類的時候,子類必須定義父類中的所有抽象方法;另外,這些方法的訪問控制必須和父類中一樣(或者更為寬松)。例如某個抽象方法被聲明為受保護(hù)的,那么子類中實現(xiàn)的方法就應(yīng)該聲明為受保護(hù)的或者公有的,而不能定義為私有的。此外方法的調(diào)用方式必須匹配,即類型和所需參數(shù)數(shù)量必須一致。例如,子類定義了一個可選參數(shù),而父類抽象方法的聲明里沒有,則兩者的聲明并無沖突。
trait代碼復(fù)用:優(yōu)先級:當(dāng)前類的成員>trait>從基類繼承的成員。同時使用多個trait時,如果有同名方法:需要用insteadof 解決沖突。
trait可以定義屬性
重載
這些魔術(shù)方法的參數(shù)都不能通過引用傳遞。
屬性重載
public void __set ( string $name , mixed $value )
public mixed __get ( string $name )
public bool __isset ( string $name )
public void __unset ( string $name )
在給不可訪問屬性賦值時,__set() 會被調(diào)用,前提是在類中定義了__set()方法,否則會報錯,下面幾種場景類似。
讀取不可訪問屬性的值時,__get() 會被調(diào)用。
當(dāng)對不可訪問屬性調(diào)用 isset() 或 empty() 時,__isset() 會被調(diào)用。
當(dāng)對不可訪問屬性調(diào)用 unset() 時,__unset() 會被調(diào)用。
參數(shù) $name 是指要操作的變量名稱。__set() 方法的 $value 參數(shù)指定了 $name 變量的值。
屬性重載只能在對象中進(jìn)行。在靜態(tài)方法中,這些魔術(shù)方法將不會被調(diào)用。所以這些方法都不能被 聲明為 static。
方法重載
public mixed __call ( string $name , array $arguments )
public static mixed __callStatic ( string $name , array $arguments )
在對象中調(diào)用一個不可訪問方法時,__call() 會被調(diào)用。前提是在類中定義了__callStatic()方法,否則會報錯,下面的__callStatic() 類似。
用靜態(tài)方式中調(diào)用一個不可訪問方法時,__callStatic() 會被調(diào)用。
對象遍歷
foreach可以遍歷對象的可見屬性。
在類的內(nèi)部用$this可以遍歷所有屬性。
魔術(shù)方法
PHP 將所有以 __(兩個下劃線)開頭的類方法保留為魔術(shù)方法。
serialize() 函數(shù)會檢查類中是否存在一個魔術(shù)方法__sleep()。如果存在,該方法會先被調(diào)用,然后才執(zhí)行序列化操作。此功能可以用于清理對象,并返回一個包含對象中所有應(yīng)被序列化的變量名稱的數(shù)組。如果該方法未返回任何內(nèi)容,則 NULL 被序列化,并產(chǎn)生一個 E_NOTICE 級別的錯誤。
__sleep() 不能返回父類的私有成員的名字。這樣做會產(chǎn)生一個 E_NOTICE 級別的錯誤。可以用 Serializable 接口來替代。
__sleep() 方法常用于提交未提交的數(shù)據(jù),或類似的清理操作。同時,如果有一些很大的對象,但不需要全部保存,這個功能就很好用。
與之相反,unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先調(diào)用 __wakeup 方法,預(yù)先準(zhǔn)備對象需要的資源。
__wakeup() 經(jīng)常用在反序列化操作中,例如重新建立數(shù)據(jù)庫連接,或執(zhí)行其它初始化操作。
當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個對象時,__invoke() 方法會被自動調(diào)用。
如果父類中的方法被聲明為 final,則子類無法覆蓋該方法。如果一個類被聲明為 final,則不能被繼承。
對象比較
當(dāng)使用比較運算符(==)比較兩個對象變量時,比較的原則是:如果兩個對象的屬性和屬性值 都相等,而且兩個對象是同一個類的實例,那么這兩個對象變量相等。
而如果使用全等運算符(===),這兩個對象變量一定要指向某個類的同一個實例(即同一個對象)。
類型約束
在方法的參數(shù)前加上參數(shù)類型,表示所需要的參數(shù)類型,如果傳的參數(shù)不是這個類型,會拋錯誤。
后期靜態(tài)綁定
static:: 不再被解析為定義當(dāng)前方法所在的類,而是在實際運行時計算的。也可以稱之為“靜態(tài)綁定”,因為它可以用于(但不限于)靜態(tài)方法的調(diào)用。栗子:
<pre>
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期靜態(tài)綁定從這里開始,如果這行代碼變成
self::who();B:test()輸出A
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); //輸出B
?>
</pre>