類型指示
大家都知道,php是一種弱類型的語言。在使用變量前不需要定義,不需要聲明變量的數據類型。這在編程中帶來很多便利,但也帶了一些隱患,特別當變量的類型變化時。在php5增加了類型指示,可以在執行過程中自動對類方法的參數類型進行判斷。這類似于java2中的rtti,配合reflection可以讓我們很好地控制對象。
<?php
interface foo {
function a(foo $foo);
}
interface bar {
function b(bar $bar);
}
class foobar implements foo, bar {
function a(foo $foo) {
// ...
}
function b(bar $bar) {
// ...
}
}
$a = new foobar;
$b = new foobar;
$a->a($b);
$a->b($b);
?>
在強類型語言中,所有變量的類型將在編譯時進行檢查,而在php中使用類型指示來對類型的檢查則發生在運行時。如果類方法參數的類型不對,將會報出類似“fatal error: argument 1 must implement interface bar…”這樣的錯誤信息。
以下代碼:
<?php
function foo(classname $object) {
// ...
}
?>
相當于:
<?php
function foo($object) {
if (!($object instanceof classname)) {
die("argument 1 must be an instance of classname");
}
}
?>
final關鍵字
php5中新增加了final關鍵字,它可以加在類或類方法前。標識為final的類方法,在子類中不能被覆寫。標識為final的類,不能被繼承,而且其中的方法都默認為final類型。
final方法:
<?php
class foo {
final function bar() {
// ...
}
}
?>
final類:
<?php
final class foo {
// class definition
}
// 下面這一行是錯誤的
// class bork extends foo {}
?>
對象復制
前面在內存管理部份說過,php5中默認通過引用傳遞對象。像使用$object2=$object1這樣的方法復制出的對象是相互關聯的。如果我們確實需要復制出一個值與原來相同的對象而希望目標對象與源對象沒有關聯(像普通變量那樣通過值來傳遞),那么就需要使用clone關鍵字。如果還希望在復制的同時變動源對象中的某些部份,可以在類中定一個__clone()函數,加入操作。
<?php
//對象復制
class mycloneable {
static $id = 0;
function mycloneable() {
$this->id = self::$id++;
}
/*
function __clone() {
$this->address = "new york";
$this->id = self::$id++;
}
*/
}
$obj = new mycloneable();
$obj->name = "hello";
$obj->address = "tel-aviv";
print $obj->id . "/n";
$obj_cloned = clone $obj;
print $obj_cloned->id . "/n";
print $obj_cloned->name . "/n";
print $obj_cloned->address . "/n";
?>
以上代碼復制出一個完全相同的對象。
然后請把function __clone()這一個函數的注釋去掉,重新運行程序。則會復制出一個基本相同,但部份屬性變動的對象。
類常量
php5中可以使用const關鍵字來定義類常量。
<?php
class foo {
const constant = "constant";
}
echo "foo::constant = " . foo::constant . "/n";
?>
__method__常量
__method__ 是php5中新增的“魔術”常量,表示類方法的名稱。
魔術常量是一種php預定義常量,它的值可以是變化的,php中的其它已經存在的魔術常量有__line__、__file__、__function__、__class__等。
<?php
class foo {
function show() {
echo __method__;
}
}
class bar extends foo {}
foo::show(); // outputs foo::show
bar::show(); // outputs foo::show either since __method__ is
// compile-time evaluated token
function test() {
echo __method__;
}
test(); // outputs test
?>