構(gòu)造函數(shù)和析構(gòu)函數(shù)
PHP 5允許開(kāi)發(fā)者在一個(gè)類(lèi)中定義一個(gè)方法作為構(gòu)造函數(shù),具有構(gòu)造函數(shù)的類(lèi)會(huì)在每次創(chuàng)建對(duì)象時(shí)先調(diào)用該方法,一般在構(gòu)造函數(shù)中做一些初始化工作。其語(yǔ)法格式如下:
void --construct ([ mixed $args [, $... ]] )
如果子類(lèi)中定義了構(gòu)造函數(shù),則不會(huì)自動(dòng)調(diào)用父類(lèi)構(gòu)造函數(shù)。要執(zhí)行父類(lèi)構(gòu)造函數(shù),需要在子類(lèi)的構(gòu)造函數(shù)中調(diào)用parent::__construct()。
<?phpclass BaseClass { function __construct() { print "對(duì)象初始化構(gòu)造函數(shù)"; }}class SubClass extends BaseClass { function __construct() { parent:__construct(); print "初始化子類(lèi)"; }}$obj = new BaseClass(); //自動(dòng)顯示:對(duì)象初始化構(gòu)造函數(shù)$obj = new SubClass(); //自動(dòng)執(zhí)行父類(lèi)和子類(lèi)的構(gòu)造函數(shù)?>
為了實(shí)現(xiàn)向后兼容性,如果PHP 5在類(lèi)中找不到__construct()函數(shù),它就會(huì)嘗試尋找舊式的構(gòu)造函數(shù),也就是和類(lèi)同名的函數(shù)。
析構(gòu)函數(shù)就是在對(duì)象的所有引用都被刪除或者當(dāng)對(duì)象被顯式銷(xiāo)毀時(shí)執(zhí)行。其語(yǔ)法格式如下:
void --destruct ( void )
例如,在下面示例中將會(huì)自動(dòng)執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)。
<?phpclass MyClass { function __construct() { print "構(gòu)造函數(shù)"; } function __destruct() { print "析構(gòu)函數(shù)"; }}$obj = new MyClass();?>
與構(gòu)造函數(shù)一樣,父類(lèi)的析構(gòu)函數(shù)不會(huì)被引擎自動(dòng)調(diào)用。要執(zhí)行父類(lèi)的析構(gòu)函數(shù),必須在子類(lèi)的析構(gòu)函數(shù)體中顯式調(diào)用parent::__destruct()。
對(duì)象繼承
繼承是面向?qū)ο缶幊痰幕咎匦?,PHP的對(duì)象模型也支持繼承。繼承將會(huì)影響到類(lèi)與類(lèi)、對(duì)象與對(duì)象之間的關(guān)系。當(dāng)擴(kuò)展一個(gè)類(lèi),子類(lèi)就會(huì)繼承父類(lèi)的所有公有和保護(hù)方法。
但是子類(lèi)的方法會(huì)覆蓋父類(lèi)的方法。
例如,在下面示例中,子類(lèi)bar繼承父類(lèi)foo的printPHP()方法,同時(shí)重寫(xiě)了父類(lèi)的printItem()方法。
<?phpclass foo{ public function printItem($string) { echo 'Foo: ' . $string; } public function printPHP(){ echo 'PHP is great.'; }}class bar extends foo{ public function printItem($string) { echo 'Bar: ' . $string; }}$foo = new foo();$bar = new bar();$foo->printItem('baz'); //顯示:Foo: baz$foo->printPHP(); //顯示:PHP is great$bar->printItem('baz'); //顯示:Bar: baz$bar->printPHP(); //顯示:PHP is great?>
繼承對(duì)于功能的設(shè)計(jì)和抽象是非常有用的,而且對(duì)于類(lèi)似的對(duì)象增加新功能就無(wú)須重新再寫(xiě)這些公用的功能。
抽象類(lèi)
抽象類(lèi)不能直接被實(shí)例化,必須先繼承該抽象類(lèi),然后再實(shí)例化子類(lèi)。抽象類(lèi)中至少包含一個(gè)抽象方法。如果類(lèi)方法被聲明為抽象的,那么其中就不能包括具體的功能實(shí)現(xiàn)。繼承一個(gè)抽象類(lèi)時(shí),子類(lèi)必須實(shí)現(xiàn)抽象類(lèi)中的所有抽象方法。如果抽象類(lèi)中某個(gè)抽象方法被聲明為protected,那么子類(lèi)中實(shí)現(xiàn)的方法就應(yīng)該聲明為protected或者public,而不能定義為private。如:
<?phpabstract class AbstractClass{ abstract protected function getValue(); //強(qiáng)制子類(lèi)必須定義的方法 public function printOut() { //普通方法(非抽象方法)print $this->getValue() . "\n"; }}class Class1 extends AbstractClass{ protected function getValue() { //具體化抽象方法 return "子類(lèi)1"; }}$class1 = new Class1;$class1->printOut(); //顯示:子類(lèi)1?>
注意:抽象類(lèi)的子類(lèi)中的普通方法執(zhí)行方式和其他類(lèi)相同。