一、簡介
自 PHP 5 起完全重寫了物件模型以獲得更佳性能和更多特性。這是自 PHP 4 以來的最大變化。 PHP 5 有完整的物件模型。
PHP 5 中的新特性包括存取控制,抽象類別和 final 類別與方法,附加的魔術方法,接口,物件複製和類型約束。
PHP 對待物件的方式與引用和句柄相同,即每個變數都持有物件的引用,而不是整個物件的拷貝。
二、基本概念
1.class
每個類別的定義都以關鍵字 class 開頭,後面跟著類別名,後面跟著一對花括號,裡麵包含有類別的屬性與方法的定義。
類別名稱可以是任何非 PHP 保留字的合法標籤。一個合法類別名稱以字母或底線開頭,後面跟著若干字母,數字或底線。以正規表示式表示為:[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. 2.new
如果在 new 之後跟著的則是包含有類別名稱的字串,則該類別的一個實例被建立。如果該類別屬於一個名字空間,則必須使用其完整名稱。
Example #3 建立一個實例<?php $instance = new SimpleClass(); //也可以这样做: $className = "Foo"; $instance = new $className(); //Foo() ?>
include_once('class1.php'); $instance = new SimpleClass(); $assigned = $instance; $reference = & $instance; $instance -> var = '$assigned will have this value'; $instance = null; //$instance和$reference变成null var_dump($instance); var_dump($reference); var_dump($assigned);
NULL
object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned will } this valueue"
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(truepool(true)
一個類別可以在宣告中用 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 起,關鍵字使用 ClassName::class 你可以取得一個字串,包含了類別 ClassName 的完全限定名稱。這對使用了 命名空間 的類別尤其有用。
namespace NS{ class ClassName{} echo ClassName::class; }輸出結果:
NSClassName