一、簡介
自 PHP 5 起完全重寫了物件模型以得到更佳效能和更多特性。這是自 PHP 4 以來的最大變化。PHP 5 具有完整的物件模型。
PHP 5 中的新特性包括存取控制,抽象類別和 final 類與方法,附加的魔術方法,介面,對象複製和類型約束。
PHP 對待對象的方式與引用和控制代碼相同,即每個變數都持有對象的引用,而不是整個對象的拷貝。
二、基本概念
1.class
每個類的定義都以關鍵字 class 開頭,後面跟著類名,後面跟著一對花括弧,裡麵包含有類的屬性與方法的定義。
類名可以是任何非 PHP 保留字的合法標籤。一個合法類名以字母或底線開頭,後面跟著若干字母,數字或底線。以Regex表示為:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*。
一個類可以包含有屬於自己的常量,變數(稱為“屬性”)以及函數(稱為“方法”)。
Example #1 簡單的類定義
<?php class SimpleClass { //聲明屬性 public $var = '1'; //聲明方法 public function displayVar(){ echo $this->var; } }?>
當一個方法在類定義內部被調用時,有一個可用的偽變數 $this。$this 是一個到主叫對象的引用(通常是該方法所從屬的對象,但如果是從第二個對象靜態調用時也可能是另一個對象)。
Example #2 $this 偽變數的樣本
<?php class A { function foo() { if(isset($this)){ echo '$this is defined ('; echo get_class($this); echo ')<br>'; }else{ echo '$this is not defined.<br>'; } } } class B { function bar() { //如果開啟了E_STRICT這一行會有警告提示 A::foo(); } } $a = new A(); $a -> foo(); //如果開啟了E_STRICT這一行會有警告提示 A::foo(); $b = new B(); $b -> bar(); //如果開啟了E_STRICT這一行會有警告提示 B::bar();?>
輸出結果:
$this is defined (A)
$this is not defined.
$this is defined (B)
$this is not defined.
2.new
要建立一個類的執行個體,必須使用 new 關鍵字。當建立新對象時該對象總是被賦值,除非該對象定義了建構函式並且在出錯時拋出了一個異常。類應在被執行個體化之前定義(某些情況下則必須這樣)。
如果在 new 之後跟著的是一個包含有類名的字串,則該類的一個執行個體被建立。如果該類屬於一個名字空間,則必須使用其完整名稱。
Example #3 建立一個執行個體
<?php $instance = new SimpleClass(); //也可以這樣做: $className = "Foo"; $instance = new $className(); //Foo()?>
在類定義內部,可以用 new self 和 new parent 建立新對象。
當把一個對象已經建立的執行個體賦給一個新變數時,新變數會訪問同一個執行個體,就和用該對象賦值一樣。此行為和給函數傳遞入執行個體時一樣。可以用複製給一個已建立的對象建立一個新執行個體。
Example #4 對象賦值
include_once('class1.php');$instance = new SimpleClass();$assigned = $instance;$reference = & $instance;$instance -> var = '$assigned will have this value';$instance = null; //$instance和$reference變成nullvar_dump($instance);var_dump($reference);var_dump($assigned);
輸出結果是:
NULL
NULL
object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned will have this value" }
PHP 5.3.0 引進了兩個新方法來建立一個對象的執行個體:
c
lass Test{ static public function getNew() { return new static; }}class Child extends Test{}$obj1 = new Test();$obj2 = new $obj1;var_dump($obj1 !== $obj2);$obj3 = Test::getNew();var_dump($obj3 instanceof Test);$obj4 = Child::getNew();var_dump($obj4 instanceof Child);
輸出結果:
bool(true)
bool(true)
bool(true)
3.extends
一個類可以在聲明中用 extends 關鍵字繼承另一個類的方法和屬性。PHP不支援多重繼承,一個類只能繼承一個基類(與java一樣都是單繼承)。
被繼承的方法和屬性可以通過用同樣的名字重新聲明被覆蓋。但是如果父類定義方法時使用了 final,則該方法不可被覆蓋。可以通過 parent:: 來訪問被覆蓋的方法或屬性。
當覆蓋方法時,參數必須保持一致否則 PHP 將發出 E_STRICT 層級的錯誤資訊。但建構函式例外,建構函式可在被覆蓋時使用不同的參數。
Example #6 簡單的類繼承:
class ExtendClass extends SimpleClass{ //重寫父類的方法 function displayVar() { echo "Extending class<br>"; parent::displayVar(); }}$extended = new ExtendClass();$extended -> displayVar();
輸出結果:
Extending class
1
4.::class
自 PHP 5.5 起,關鍵詞 class 也可用於類名的解析。使用 ClassName::class 你可以擷取一個字串,包含了類 ClassName 的完全限定名稱。這對使用了 命名空間 的類尤其有用。
Example #7 類名的解析
namespace NS{ class ClassName{} echo ClassName::class;}
輸出結果:
NS\ClassName