// 三大特性
封裝:隱藏內(nèi)部是吸納,僅開發(fā)接口。
繼承:一個對象的成員被另一個對象所使用。語法上體現(xiàn)為代碼的共用。
多態(tài):多種形態(tài)。
/* 【類和對象】 */
成員:
類成員:類常量、靜態(tài)屬性、靜態(tài)方法
對象成員:非靜態(tài)屬性、非靜態(tài)方法
# 除此外,類不能包含任何其他東西?。?!
類名、方法名、屬性名均不區(qū)分大小寫
$this代表本對象,self代表本類,parent代表父類
類和函數(shù)均可被事先編譯(僅作為最外層時)
類的定義必須在單一的PHP區(qū)塊內(nèi),不能被多個PHP標簽分割
// 構造方法
- 具有構造函數(shù)的類會在每次創(chuàng)建新對象時先調(diào)用此方法
void __construct([ mixed $args [, $... ]] ) - 構造方法所需參數(shù)由new實例化對象時,給類增加參數(shù)值。
- 構造方法也可以被手動調(diào)用。
- 5.3.3版本以前,支持于類名同名的方法作為構造方法。
- 兩種沖突時,__construct 優(yōu)先
// 析構方法
- 析構函數(shù)會在到某個對象的所有引用都被刪除或者當對象被顯式銷毀時執(zhí)行。
void __destruct( void )
作用:釋放對象所占用的資源
調(diào)用的時機
- 腳本結束時所有資源均被釋放,包括對象
- 手動刪除對象時
- 保存對象的變量被賦予新值時(任何值,包括null)
- 在使用exit()終止腳本運行時也會被調(diào)用
// 靜態(tài)成員(static關鍵字)
- 聲明類成員或方法為static,就可以不實例化類而直接訪問。
- 靜態(tài)成員(屬性或方法)均屬于類,故不能通過$this或->訪問。
- 靜態(tài)成員是所有對象共享,屬于類。
- 靜態(tài)成員用類調(diào)用,非靜態(tài)成員用對象調(diào)用。
靜態(tài)屬性
- 靜態(tài)屬性不可以由對象通過->操作符來訪問。
- 靜態(tài)屬性只能被初始化為一個字符值或一個常量,不能使用表達式。 所以你可以把靜態(tài)屬性初始化為整型或數(shù)組,但不能指向另一個變量或函數(shù)返回值,也不能指向一個對象。
靜態(tài)方法
- 由于靜態(tài)方法不需要通過對象即可調(diào)用,所以偽變量$this在靜態(tài)方法中不可用。
- 用::方式調(diào)用一個非靜態(tài)方法會導致一個E_STRICT級別的錯誤。
// 訪問解析操作符(::)
- 可以用于訪問靜態(tài)成員、方法和常量,還可以用于覆蓋類中的成員和方法。
- 當在類的外部訪問這些靜態(tài)成員、方法和常量時,必須使用類的名字。
- self 和 parent 這兩個特殊的關鍵字是用于在類的內(nèi)部對成員或方法進行訪問的。
// 訪問辨析
- 對象成員,內(nèi)部通過$this指定,外部通過對象名指定,均用->訪問,訪問屬性時不需加$。
對象名->屬性名 對象名->方法名() $this->屬性名 $this->方法名() - 類成員,內(nèi)部通過self或parent指定,外部通過類名指定,均用::訪問,訪問屬性時需加$。
類名::$屬性名 類名::方法名() self::$屬性名 self::方法名() - 特殊:也可以通過對象訪問類成員。(不建議)
對象名::$類屬性名 $this::$類屬性名 對象名::$類方法名() $this::類方法名()
對象成員訪問用->,類成員訪問用::
- 無論是靜態(tài)方法還是非靜態(tài)方法,均可通過類或對象進行訪問。
- 靜態(tài)屬性通過類訪問,靜態(tài)方法通過對象訪問。
- 只有使用對象調(diào)用非靜態(tài)方法時,$this才可以使用!
- 靜態(tài)方法不可使用$this。
- 類可以調(diào)用對象方法,但注意方法內(nèi)不能有$this。
- 非靜態(tài)方法可以調(diào)用靜態(tài)屬性或靜態(tài)方法,反之不可以。
// 類常量
- 常量的值將始終保持不變。
- 在定義和使用常量的時候不需要使用$符號。
- 常量的值必須是一個定值,不能是變量,類屬性或其它操作(如函數(shù)調(diào)用)的結果。
定義:const 常量名 = 常量值;
- 不需要加public等訪問修飾限定符
- 類常量屬于類,使用類訪問,類名::類常量 或 self::類常量
// 自動加載對象
- 在試圖使用尚未被定義的類時自動調(diào)用 __autoload 函數(shù)
- 自動加載使用到的類名文件(根據(jù)類名找相應名稱的文件,故需類名與類文件名一致)
- 每個需要加載類的文件都需要存在__autoload函數(shù)
- 將__autoload函數(shù)寫入單獨的文件,每個需要用到類的文件再require該函數(shù)文件
- __autoload 參數(shù)是類名
function __autoload($class_name) {
require_once $_SERVER["DOCUMENT_ROOT"] . "/class/$class_name.php";
}
// $_SERVER["DOCUMENT_ROOT"] 當前運行腳本所在的文檔根目錄 - 可以通過類名,來推導出類所在的文件名!
- 如果一個項目存在多個自動加載函數(shù)時,定義一個可以完成加載的普通函數(shù),并在函數(shù)之前使用spl_autoload_register注冊該函數(shù)。
spl_autoload_register
- 注冊__autoload()函數(shù)
bool spl_autoload_register ([ callback $autoload_function ] ) - 可以注冊多個自動加載函數(shù),先注冊的先執(zhí)行
- 一旦注冊自動加載函數(shù),__autoload就失效。
- 注冊函數(shù)時,參數(shù)為函數(shù)名(注意加引號);注冊方法時,參數(shù)為數(shù)組
注冊類或對象的方法為自動加載方法時,參數(shù)需為數(shù)組:
spl_autoload_register(array(CLASS, '__autoload'));
CLASS表示當前類名,若是對象可用$this,詳細見手冊
對象序列化
- 只能序列化對象內(nèi)部的數(shù)據(jù),即非靜態(tài)屬性。
需在反序列化對象之前加載類,也可以觸發(fā)自動加載機制。
__sleep 序列化需序列化的屬性。
- 提交未提交的數(shù)據(jù),或類似的清理操作,部分串行化對象。
- 返回一個包含對象中所有應被序列化的變量名稱的數(shù)組
__wakeup 反序列化時,預先準備對象需要的資源
- 重新建立數(shù)據(jù)庫連接,或執(zhí)行其它初始化操作
public function __sleep() {
return array('server', 'username', 'password', 'db');
}
public function __wakeup() {
$this->connect();
}
// 對象繼承
class 子類名 extends 父類 {}
如果一個對象是子類的對象,那么同時也是父類的對象。
單繼承:一個類只能繼承一個父類,不能同時繼承多個類。但一個父類可以被多個子類繼承。
instanceof 判斷某對象是否為某類的對象
對象名 instanceof 類名
// 訪問控制
public 公有的(繼承鏈、本類、外部均可訪問)
protected 保護的(僅繼承鏈、本類可訪問)
private 私有的(僅本類可訪問)
根據(jù)成員定義位置、訪問位置判斷。
兼容性問題
- 聲明屬性時,var關鍵字聲明的默認為public權限
- 聲明方法時,省略訪問修飾符,默認為public權限
// 重寫 override
$this代表本對象,被誰調(diào)用,就代表哪個對象。
- 繼承時,子類成員名于父類成員名發(fā)生沖突,則子類成員會重寫父類成員。
- 屬性和方法均可被子類重寫。
- 當父類的方法或屬性已經(jīng)不滿足子類的需求,則需要重寫。
- 也可能因為命名不規(guī)范導致重寫。
私有屬性不能被重寫,每個私有屬性都會被記錄。在記錄屬性名的同時,還會記錄類。
如果有內(nèi)置函數(shù)被重寫,則可調(diào)用父類方法。如調(diào)用父類構造方法parent::__construct()
重寫限制
訪問限制:
子類的成員的訪問控制必須相等或弱于父類。
方法參數(shù)限制:
參數(shù)數(shù)量必須相同,參數(shù)名可不同。
$this確定原則
$this為調(diào)用該方法的對象,表示該方法的執(zhí)行環(huán)境對象。
- 對象調(diào)用
- 環(huán)境的傳遞。如果當前調(diào)用時,不能確定$this的值(靜態(tài)調(diào)用),此時靜態(tài)調(diào)用所處對象環(huán)境會傳遞到被調(diào)用的方法內(nèi)。
$this并非永遠代表本對象,而是由方法的執(zhí)行環(huán)境決定。
抽象類
關鍵字:abstract
抽象類不能直接被實例化,必須先繼承該抽象類,然后再實例化子類。
抽象類中至少要包含一個抽象方法。非抽象類不能包含抽象方法。
如果類方法被聲明為抽象的,那么其中就不能包括具體的功能實現(xiàn)。抽象方法不能包含大括號及方法體。
繼承一個抽象類的時候,子類必須實現(xiàn)抽象類中的所有抽象方法。
即,子類必須重寫抽象父類中的所有抽象方法。
另外,這些方法的可見性必須和抽象類中一樣(或者更為寬松)。
即,如果抽象類中某個抽象方法被聲明為protected,那么子類中實現(xiàn)的方法就應該聲明為protected或者public,而不能定義為private。
- 抽象類的子類中的普通方法執(zhí)行方式和其他類相同。
- 作用:
- 繼承,為擴展類,統(tǒng)一公共操作。
- 限制結構(規(guī)范)。規(guī)范子類的結構。
final
如果父類中的方法被聲明為final,則子類無法覆蓋(重寫)該方法。
如果一個類被聲明為final,則不能被繼承。
但加有final關鍵字的類依舊能被實例化!
// 靜態(tài)延遲綁定self::,代表本類(當前代碼所在類) 永遠代表本類,因為在類編譯時已經(jīng)被確定。 即,子類調(diào)用父類方法,self卻不代表調(diào)用的子類。static::,代表本類(調(diào)用該方法的類) 用于在繼承范圍內(nèi)引用靜態(tài)調(diào)用的類。 運行時,才確定代表的類。 static::不再被解析為定義當前方法所在的類,而是在實際運行時計算的。// 對象的遍歷(迭代)- 對象通過屬性保存數(shù)據(jù),故遍歷對象的屬性。- foreach語言結構,獲得屬性名和屬性值。 foreach ($obj as $p_name => $p_value) {}# 自定義遍歷(迭代器Iterator)Iterator - 可在內(nèi)部迭代自己的外部迭代器或類的接口Iterator::current — 返回當前元素Iterator::key — 返回當前元素的鍵Iterator::next — 向前移動到下一個元素Iterator::rewind — 返回到迭代器的第一個元素Iterator::valid — 檢查當前位置是否有效# 對象的克隆//對象之間的傳值是[引用]傳遞??寺。盒聦ο?= clone 舊對象 - 所有的引用屬性仍然會是一個指向原來的變量的引用。 __clone()方法在對象被克隆時自動調(diào)用。注意:構造方法對應實例化(new),克隆方法對應克隆(clone)。// 單例模式#三私一公單例模式(Singleton)用于為一個類生成一個唯一的對象。最常用的地方是數(shù)據(jù)庫連接。使用單例模式生成一個對象后,該對象可以被其它眾多對象所使用。# 防止一個類被實例化多次class MySQLDB { private static $instance = null; // 存類實例在此屬性中 // 構造方法聲明為private,防止直接創(chuàng)建對象 private function __construct() {} public static function getInstance() { if(! self::$instance instanceof static) { self::$instance = new static; } return self::$instance; } private function __clone() {} // 阻止用戶復制對象實例}# 重載 overload指動態(tài)地"創(chuàng)建"類屬性和方法用戶可以自由的為對象添加額外的屬性,該特性就是重載。所有的重載方法都必須被聲明為public。當調(diào)用當前環(huán)境下未定義或不可見的類屬性或方法時,重載方法會被調(diào)用。重載相關魔術方法的參數(shù)都不能通過引用傳遞。
屬性重載
- 處理不可訪問的屬性
屬性重載只能在對象中進行。
屬性重載對于靜態(tài)屬性無效
在靜態(tài)方法中,這些魔術方法將不會被調(diào)用。所以這些方法都不能被聲明為static。
__set 在給不可訪問的屬性賦值時
public void __set(string $name, mixed $value)
作用:批量管理私有屬性,間接保護對象結構
__get 讀取不可訪問的屬性的值時
public mixed __get(string $name)
__isset 當對不可訪問的屬性調(diào)用isset()或empty()時
public bool __isset(string $name)
__unset 當對不可訪問的屬性調(diào)用unset()時
public void __unset(string $name)
方法重載
- 處理不可訪問的方法
__call 當調(diào)用一個不可訪問的非靜態(tài)方法(如未定義,或者不可見)時自動被調(diào)用
public mixed __call(string $name, array $arguments)
__callStatic 當在調(diào)用一個不可訪問的靜態(tài)方法(如未定義,或者不可見)時自動被調(diào)用
public static mixed __callStatic(string $name, array $arguments)
$name參數(shù)是要調(diào)用的方法名稱。$arguments參數(shù)是一個數(shù)組,包含著要傳遞給方法的參數(shù)。
// 類型約束
函數(shù)的參數(shù)可以指定只能為對象或數(shù)組
限定為對象則在形參前加類名,限定為數(shù)組則在形參前加array
類型約束允許NULL值
類型約束不只是用在類的成員方法里,也能使用在函數(shù)里。
// 類與對象·關鍵字
this 代表本對象
public 公有的(繼承鏈、本類、外部均可訪問)
protected 保護的(僅繼承鏈、本類可訪問)
private 私有的(僅本類可訪問)
parent:: 代表父類
self:: 代表本類(當前代碼所在類)
static:: 代表本類(調(diào)用該方法的類)
static 靜態(tài)成員(屬性、方法),所有對象均可使用,外部也可直接使用或修改,靜態(tài)方法不可訪問非靜態(tài)成員
final 方法用final不可被子類重載,類用final不可被繼承(方法、類)
const 類常量(屬性)
abstract 抽象類
interface 接口
extends 類繼承(子接口繼承接口、其他普通類繼承)
implements 接口實現(xiàn)(類實現(xiàn)接口、抽象類實現(xiàn)借口)(對接口的實現(xiàn)和繼承均可有多個)
Iterator 內(nèi)置接口(迭代)
clone 克隆
instance 實例
instanceof 某對象是否屬于某類
/* 【類與對象相關函數(shù)】 */
class_alias([$original [,$alias]]) 給類取別名
class_exists($class [,$autoload]) 檢查類是否已定義
interface_exists($interface [,$autoload]) 檢查接口是否已被定義
method_exists($obj, $method)檢查類的方法是否存在
property_exists($class, $property) 檢查對象或類是否具有該屬性
get_declared_classes(void) 返回由已定義類的名字所組成的數(shù)組
get_declared_interfaces(void) 返回一個數(shù)組包含所有已聲明的接口
get_class([$obj]) 返回對象的類名
get_parent_class([$obj]) 返回對象或類的父類名
get_class_methods($class) 返回由類的方法名組成的數(shù)組
get_object_vars($obj) 返回由對象屬性組成的關聯(lián)數(shù)組
get_class_vars($class) 返回由類的默認屬性組成的數(shù)組
is_a($obj, $class) 如果對象屬于該類或該類是此對象的父類則返回TRUE
is_subclass_of($obj, $class) 如果此對象是該類的子類,則返回TRUE
get_object_vars($obj) 返回由對象屬性組成的關聯(lián)數(shù)組
// 魔術方法
__construct 構造方法
__destruct 析構方法
__clone 克隆對象
__sleep 序列化對象
__wakeup 反序列化對象
__autoload 自動加載,使用類但未找到時
__toString 對象被當作字符串使用時
__invoke 當嘗試以調(diào)用函數(shù)的方式調(diào)用一個對象時
// 常用類# PHP手冊 -> 預定義類Closure 閉包類,匿名函數(shù)對象的final類stdClass 標準類,通常用于對象類保存集合數(shù)據(jù)__PHP_Incomplete_Class 不完整類,當只有對象而沒有找到類時,則該對象被認為是該類的對象Exception 異常類PDO 數(shù)據(jù)對象類// 魔術常量DIR 文件所在的目錄LINE 文件中的當前行號 FILE 文件的完整路徑(絕對路徑)和文件名CLASS 類的名稱METHOD 類的方法名,包含類名和方法名FUNCTION 函數(shù)名稱,用在方法內(nèi)只表示方法名// 反射機制 Reflection作用:1. 獲取結構信息 2. 代理執(zhí)行ReflectionClass 報告一個類的有關信息ReflectionMethod 報告一個方法的有關信息ReflectionClass::export 輸出類結構報告# 代理執(zhí)行實例化 ReflectionFunction 類的對象 $f = new ReflectionFunction('func'); // func為函數(shù)func($p) $f->invoke('param');
// 接口
關鍵字:interface
- 對象提供的與對象交互的方式就是接口。
- 使用接口可以指定某個類必須實現(xiàn)哪些方法,但不需要定義這些方法的具體內(nèi)容。
- 通過interface來定義一個接口,就像定義一個標準的類一樣,但其中定義所有的方法都是空的。
- 接口中定義的所有屬性和方法都必須是public,可省略public關鍵字。
- 接口中也可以定義常量(const)。接口常量和類常量的使用完全相同。
可以用::訪問。接口名::常量名,實現(xiàn)類::常量名。
它們都是定值,可以被子類或子接口使用,但不能修改。 - 接口不能定義屬性!
定義接口
interface 接口名 {
接口內(nèi)容(公共方法聲明的集合)
}
接口實現(xiàn)
- 要實現(xiàn)一個接口,可以使用implements操作符。
- 類中必須實現(xiàn)接口中定義的所有方法,否則會報一個fatal錯誤。
- 如果要實現(xiàn)多個接口,可以用逗號來分隔多個接口的名稱。
- 實現(xiàn)多個接口時,接口中的方法不能有重名。
- 接口也可以繼承,通過使用extends操作符。
class 類名 implements 接口名 {
接口方法的實現(xiàn)
}
注意
1. 類與抽象類之間是繼承關系,類與接口之間是實現(xiàn)關系。
2. 類與抽象類是單繼承,類與接口是多實現(xiàn)。
3. 接口不是類,限制類的結構。
4. 接口與接口之間是多繼承。用extends關鍵字。
interface I_C extends I_A, I_B {}
本文轉載自http://blog.csdn.net/lhorse003/article/details/71170155