13.自動(dòng)加載類 __autoload()函數(shù)
很多開發(fā)者寫面向?qū)ο蟮膽?yīng)用程序時(shí),對(duì)每個(gè)類的定義建立一個(gè) PHP 源文件。一個(gè)很大的煩惱是不得不在每個(gè)腳本(每個(gè)類一個(gè)文件)開頭寫一個(gè)長(zhǎng)長(zhǎng)的包含文件的列表。
在軟件開發(fā)的系統(tǒng)中,不可能把所有的類都寫在一個(gè)PHP文件中,當(dāng)在一個(gè)PHP文件中需要調(diào)用另一個(gè)文件中聲明的類時(shí),就需要通過include把 這個(gè)文件引入。不過有的時(shí)候,在文件眾多的項(xiàng)目中,要一一將所需類的文件都include進(jìn)來,是一個(gè)很讓人頭疼的事,所以我們能不能在用到什么類的時(shí) 候,再把這個(gè)類所在的php文件導(dǎo)入呢?這就是我們這里我們要講的自動(dòng)加載類。
在 PHP 5 中,可以定義一個(gè)\ __autoload()函數(shù),它會(huì)在試圖使用尚未被定義的類時(shí)自動(dòng)調(diào) 用,通過調(diào)用此函數(shù),腳本引擎在 PHP 出錯(cuò)失敗前有了最后一個(gè)機(jī)會(huì)加載所需的類, __autoload()函數(shù)接收的一個(gè)參數(shù),就是你想加載的類的 類名,所以你做項(xiàng)目時(shí),在組織定義類的文件名時(shí),需要按照一定的規(guī)則,最好以類名為中心,也可以加上統(tǒng)一的前綴或后綴形成文件名,比如 xxx_classname.php、classname_xxx.php以及就是classname.php等等。
function __autoload($classname) {
require_once $classname . '.php';
}
// MyClass1類不存在時(shí),自動(dòng)調(diào)用__autoload()函數(shù),傳入?yún)?shù)”MyClass1”
$obj = new MyClass1();
// MyClass2類不存在時(shí),自動(dòng)調(diào)用__autoload()函數(shù),傳入?yún)?shù)”MyClass2”
$obj2 = new MyClass2();
注意:
__autoload() 是專門為 類的不存在 而設(shè)計(jì)的?。?!很多框架利用這個(gè)函數(shù),實(shí)現(xiàn) 類文件的自動(dòng)加載 ?。?!
14.抽象方法和抽象類(abstract)
在OOP語言中,一個(gè)類可以有一個(gè)或多個(gè)子類,而每個(gè)類都有至少一個(gè)公有方法做為外部代碼訪問其的接口。而抽象方法就是為了方便繼承而引入的,我們先來看一下抽象類和抽象方法的定義再說明它的用途。
什么是抽象方法?我們?cè)陬惱锩娑x的沒有方法體的方法就是抽象方法,所謂的沒有方法體指的是,在方法聲明的時(shí)候沒有大括號(hào)以及其中的內(nèi)容,而是直接在聲明時(shí)在方法名后加上分號(hào)結(jié)束,另外在聲明抽象方法時(shí)還要加一個(gè)關(guān)鍵字“abstract”來修飾;
例如:
abstract function fun1();
abstract function fun2();
什么是抽象類呢?只要一個(gè)類里面有一個(gè)方法是抽象方法,那么這個(gè)類就要定義為抽象類,抽象類也要使用“abstract”關(guān)鍵字來修飾;在抽象類里面可以有不是抽象的方法和成員屬性,但只要有一個(gè)方法是抽象的方法,這個(gè)類就必須聲明為抽象類,使用”abstract”來修飾。
例如:
abstract class Demo {
var $test;
abstract function fun1();
abstract function fun2();
function fun3() {
...
}
}
那么抽象類我們?cè)趺词褂媚??最重要的一點(diǎn)就是抽象類不能產(chǎn)生實(shí)例對(duì)象, 所以也不能直接使用,前面我們多次提到過類不能直接使用,我們使用的是通過類實(shí)例化出來的對(duì)象,那么抽象類不能產(chǎn)生實(shí)例對(duì)象我們聲明抽象類有什么用呢?我們是將抽象方法是做為子類重載的模板使用的,定義抽象類就相當(dāng)于定義了一種規(guī)范,這種規(guī)范要求子類去遵守,子類繼承抽象類之后,把抽象類里面的抽象方法按 照子類的需要實(shí)現(xiàn)。子類必須把父類中的抽象方法全部都實(shí)現(xiàn),否則子類中還存在抽象方法,那么子類還是抽象類,還是不能實(shí)例化類;
為什么我們非要從抽象類中繼承呢?因?yàn)橛械臅r(shí)候我們要實(shí)現(xiàn)一些功能就必須從抽象類中繼承,否則這些功能你就實(shí)現(xiàn)不了,如果繼承了抽象類,就要實(shí)現(xiàn)類其中的抽象方法;
abstract class Demo {
var $test;
abstract function fun1();
abstract function fun2();
function fun3() {
...
}
}
$demo = new Demo(); // 抽象類不能產(chǎn)生實(shí)例對(duì)象,所以這樣做是錯(cuò)的,實(shí)例化對(duì)象交給子類
class Test extends Demo {
function fun1() {
...
}
function fun2() {
...
}
}
$test = new Test(); // 子類可以實(shí)例化對(duì)象,因?yàn)閷?shí)現(xiàn)了父類中所有抽象方法
在設(shè)計(jì)模式中,常用于工廠模式。