PHP 5 物件新語法簡介

我想現在PHP官網的兩份中文說明還是原封不動,坊間看過幾本書,說的卻也不太詳盡,所以現在寫出來給大家看看 5 在物件導向語法上的新變動。

PHP 的語法給人的印象是繼承自三種語言:Perl,C++,Java(Multiple Inheritance? orz)。當中oo部份有不少符號及關鍵字均借用於 Java,所以說懂 Java 一點有助了解。

建構子和解構子 (Constructor and Destructor)
首先,跟以往 PHP 4 語法不一樣,建構子 (constructor) 的新名稱是 __construct() ,再不是跟類別名稱同名。而取自 C++,現在PHP 5 也有解構子(destructor) 的method __destruct()。解構子能於物件再沒有參考變數的時候自動呼叫,不像 Java 一樣要待 GC 有空才願意幫你清理掉。只要將任何指到物件的變數指定為 0 即可。

存取限定
關於存取層次方面,PHP 5 終於達到物件封裝的要求,允許將成員變數及成員函數設為 private,protected 或 public。語法很像 Java,如:
class foo {
public $bar1;
private $bar2;
private $bar3;
public function func1() { return $this->bar1 . $this->bar2; }
protected function func2() { return $this->bar3; }
}
class foo2 extends foo {
protected function func2() { return parent::func1(); }
}

protected 關鍵字允許繼將成員函式/變數重載 (overridding),卻不像 public 可以於物件外存取。

靜態成員 (static member)
靜態成員是可以於物件未被實體化前使用之變數,功能對應 Java 的 static 關鍵字。使用的語法是classname::static_method(),而記緊 classname 前面沒 $,因為它不是物件實體。static 還有一個兄弟 const,特性很像 static,成員卻不能變動值,也不能應用在成員函數上。存取方法跟 static 一樣,使用類別存取運算子 :: 。

抽象類別及介面
abstract (抽象)關鍵字明顯來自 Java。用途一樣,要子類別「一定要實作此函式名稱」(也就是 C++ 的 virtual)。
abstract class foo {
abstract public bar();
abstract protected bar2();
public function bar3() { ... } //共用成員函數
}
class foo2 extends foo {
public function bar() { ... }
} //出現問題,bar2 尚未實作

Interface (介面)是 PHP 5 的另一新語法(又完全借用於 Java orz)。Interface 也強制其使用者(class)實作指定的成員/成員函數,不過一個類別可使用多個介面。
interface i1 {
const c1 = 3;
public function m1();
}
interface i2 {
public function m2();
}
class foo implements i1, i2 {
public function i1() { ... }
public function i2() { ... }
}

甚麼時候該用抽象類別,甚麼時候要用介面呢?當要寫一大堆使用不少相同函式,但其他成員函式的實作方法也不一樣的時候,該用抽象類別。反而介面較適合使用在函式呼叫的引數規限(有說此乃委任(Delegate)。下面是範例。
interface i1 {
public function if1($var);
}
class foo {
public function h1($var) {
return $var."hello";
}
}
class bar implements i1 {
public function if1($var) {
return $var. "I use if1!!!";
}
}
function use_i(i1 $var) {
echo $var->if1("In function i ");
}
$f = new foo();
$b = new bar();
use_i($b);
use_i($f); //出現錯誤,沒有用上 i1 介面!

Leave a Reply

Your email address will not be published. Required fields are marked *