標籤:程式設計 物件導向
PHP物件導向程式設計
物件導向的程式設計(Object Oriented Programming)
一、物件導向程式設計的概念
PHP引進的物件導向的設計方法,將資料及處理資料的相應函數“封裝”到一個“類(class)”中。類的執行個體稱為“對象”。在一個對象內,只有屬於該對象的函數才可以存取該對象的資料。
物件導向的程式設計有三個主要特徵:封裝、繼承和多態。
1.封裝
封裝是將資料和代碼捆綁到一起,避免外界的幹擾和不確定性。在PHP中,封裝是通過類來實現的。類是抽象資料類型的實現,一個類的所有對象都具有相同的資料結構,並且共用相同的實現操作的代碼,而各個對象又有著各自不同的狀態,即私人的儲存。因此,類是所有對象的共同的行為和不同狀態的結合體。
由一個特定的類所建立的對象稱為這個類的執行個體,因此類是對象的抽象及描述,它是具有共同行為的若干對象的統一描述體。類中還包含產生對象的具體方法。
2.繼承
類提供了建立新類的一種方法,再藉助於“繼承”,這一重要機制擴充了類的定義,實現了物件導向的優越性。
繼承提供了建立新類的方法:一個新類可以通過對已有的類進行修改或擴充來滿足新類的需求。新類共用已有類的行為,而自己還具有修改的或額外添加的行為。因此,可以說繼承的本質特徵是行為共用。
從一個類繼承定義的新類,將繼承已有類的所有方法和屬性,並且可以添加所需要的新的方法和屬性。新類被稱為已有類的子類,已有類稱為父類,又叫基類。
3.多態
不同的類對於不同的操作具有不同的行為,稱為多態。多態機制使具有不同的內部結構的對象可以共用相同的外部介面,通過這種方式減少代碼的負責度。
二、在PHP中建立類、屬性和方法
類是物件導向程式設計的核心,它是一種資料類型。類由變數和函數組成,在類裡面,變數稱為屬性或成員變數,函數稱為方法。定義類的文法格式如下:
class classname{ [var $property[=value];...] [function functionname($args) { //代碼 } ]}
在PHP中,類需要使用class關鍵字來定義,後面跟類名classname。類的命名規則要符合PHP標記的命名規則,並且不能是PHP的保留字。類名後跟一對花括弧,花括弧裡麵包含類的屬性和方法。
在類中,使用關鍵字var來聲明變數,即類的屬性。使用關鍵字function來定義函數,即類的方法。
注意:在定義屬性時,給屬性賦的值不能使用定界符,不能是運算式,不能包含括弧,不能通過其他變數賦值。另外,在類的方法內部的變數只是普通變數,不屬於類的屬性,因為它的作用範圍只限於方法內部。不能將類的定義放到多個檔案或多個PHP塊中。
三、類的執行個體化與訪問
在聲明一個類後,類只存在於檔案中,程式不能調用。需要建立一個對象後程式才能使用,建立一個類對象的過程叫做類的執行個體化。類的執行個體化使用new關鍵字,關鍵字後面需要指定執行個體化的類名。
在一個類中,可以訪問一個特殊的指標“$this”。如果當前類有一個屬性$attribute,則在類的內部要訪問這個屬性時,可以使用“$this->attribute”來引用。
在對象唄建立之後,可以在類的外部對該對象的屬性和方法進行訪問,訪問的方法是在對象後面使用“->”符合加上要訪問的屬性和方法。注意屬性的前面沒有“$”。
說明:有的類對類中的屬性進行了存取控制,如果設定了類外部不能訪問類中屬性時,直接存取將會發生錯誤。
四、類的存取控制
在PHP5中,存取修飾詞public、private和protected,它們可以控制屬性和方法的可見度,通常放置在屬性和方法的聲明之前。
①public。聲明為公用的屬性和方法,可以在類的外部或內部進行訪問。public是預設選項,如果沒有為一個屬性或方法制定修飾符,那麼它將是public的。
②private。聲明為私人的屬性和方法,只可以在類的內部進行訪問,私人的屬性和方法將不會被繼承。
③protected。聲明為被保護的屬性和方法,只可以在類的內部和子類的內部進行訪問。
在進行類的設計時,通常將類的屬性設為私人的,而將大多數方法設為公有的。這樣,類以外的代碼不能直接存取類的私人資料,從而實現了資料的封裝,而公有的方法可為內部的私人資料提供外部介面,但介面實現的細節在類外又是不可見的。
五、靜態屬性和方法
所謂“靜態”是指所定義的屬性和方法與類的執行個體無關,只與類本身有關。靜態屬性和方法一般用於包含類要封裝的資料和功能,可以由所有類的執行個體共用。在類裡面可以使用static關鍵字定義靜態屬性和方法。
訪問靜態屬性和方法時需要使用到範圍解析符“::”,格式如下:
classname::$attribute; //訪問靜態屬性
classname::Cfunction([$args,...]) //訪問靜態方法
注意:只有靜態屬性和方法才能使用範圍解析符,不能使用範圍解析符訪問非靜態屬性和方法。
六、建構函式和解構函式
建構函式是類中的一個特殊函數,當建立一個類的執行個體時,建構函式將被自動調用,主要功能通常是對類中的對象完成初始化工作。與建構函式相對的是解構函式,解構函式在類的對象被銷毀時被自動調用。
①建構函式。在PHP5中,建構函式的名稱為“__construct”,"contruct"前面是兩根底線。如果一個類同時擁有__contruct建構函式和類名相同的函數,PHP5將把__construct看做是建構函式。PHP中的建構函式可以帶參數,也可以不帶參數。
②解構函式。類的解構函式的名稱是__destruct,如果在類中聲明了__destruct函數,PHP將在對象被銷毀前調用解構函式將對象從記憶體中銷毀,節省伺服器資源。
如果建構函式中帶了參數,在建立對象時也可以在類名後面為建構函式指定參數。
七、類的繼承
1.子類訪問父類
在PHP中,允許通過繼承其他類的方法來調用這些類裡已經定義好的屬性和方法,PHP不支援多繼承,所以一個子類只能繼承一個父類。可以使用extends關鍵字來指明類與類之間的關係。
類B繼承與類A,所以類B的對象可以訪問類A的屬性和方法,但A中的private的屬性和方法將不能被繼承,A中protected的屬性和方法只能在B的內部訪問,類B建立的對象無法訪問,否則將產生錯誤。B作為A的子類,具有類A一樣的資料和功能,此外B還可以聲明自己的屬性和方法。
繼承是單方向的,子類可以從父類中繼承特性,但父類卻無法從子類中繼承特性。
如果子類中沒有自己的建構函式,那麼子類在執行個體化時會自動調用父類的建構函式。如果子類中有自己的建構函式,則執行自己的建構函式。
如果要在子類中調用父類的方法,除了使用“$this->”外,還可以使用parent關鍵字加範圍解析符,如“parent::functionname()”。建議使用後一種方法,因為前面的方法容易造成子類和父類方法結構不清。而對於父類的屬性,在子類中只能使用“$this->”來訪問,屬性是不區分父類和子類的。
繼承可以是多重的。例如:類B繼承了類A,類C繼承了類B,那麼類C也就繼承了類A和類B的父類的所有特性。
2.重載
方法的重載是指在一個類中可以定義多個擁有相同名稱的方法,通過參數個數和類型來區分這些方法。在PHP中可以通過類的繼承,在子類中定義和父類中相同名稱的方法來實作類別似方法重載的特性。
3.使用final關鍵字
PHP中final關鍵字,在聲明類時使用這個關鍵字,將使這個類不能被繼承。另外,如果將final關鍵字用於聲明類中的方法,該方法將不能在任何子類中重載。
注意:final關鍵字只能用於聲明類和方法。
八、抽象類別和介面
1.抽象類別
抽象類別是一種特殊的類,使用關鍵字abstract來定義,不能被執行個體化。一個抽象類別中至少包含一個抽象方法,抽象方法也是由abstract關鍵字來定義。抽象方法只提供了方法的聲明,不提供方法的實現。例如:
abstract function func($name,$number);
包含抽象方法的類必須是抽象類別。
抽象類別不能用於建立對象,所以只能通過繼承來使用。繼承抽象類別的子類,必須重載抽象類別中的所有抽象方法才能被執行個體化。
2.介面
PHP只能提供單繼承,即一個類只能有一個父類。介面是一個特殊的抽象類別,使用interface關鍵字取代class關鍵字來定義。抽象類別中允許存在非抽象的方法和屬性,而在介面中定義的方法都是抽象方法。在介面中不能使用屬性,但可以使用const關鍵字定義的常量。例如:
const con="tom";
介面的定義方法和定義類的方法類似,在介面中定義抽象方法不適用abstract關鍵字。
注意:介面中所有的方法都要求使用public定義,由於預設的存取修飾詞就是public,所以可以省略。
介面和類一樣,也支援繼承,介面之間的繼承也使用extends關鍵字。例如:
<?phpinterface A{ const name=""; function show();}interface B extends A{ function getname();}?>
定義了介面之後可以將其執行個體化,介面的執行個體化稱為介面的實現。要實現一個介面需要一個子類來實現介面的所有抽象方法。定義介面的子類使用implements關鍵字,另外,一個子類還可以實現多個介面,這樣就解決了多繼承的問題。
一個子類還可以同時繼承一個父類和多個介面。
九、類的魔術方法
PHP規定以兩個底線“__”開頭的方法都保留為魔術方法,所以在定義函數名時盡量不要用"__"開頭,除非是為了重載已有的魔術方法。
1.複製對象
PHP使用clone關鍵字建立一個與原對象擁有相同屬性和方法的對象,這種方法用於通過一個類執行個體化兩個類的對象的情況下。例如:
$new_obj=clone $old_obj;
$new_obj是新的對象名,$old_obj是要複製的對象名。
複製後的對象擁有複製對象的全部屬性,如果需要改變這些屬性,可以使用PHP提供的魔術方法__clone。這個方法在複製一個對象時將被自動調用,類似於__construct和__destruct方法。在__clone方法中,可以定義確切的複製行為或執行一些操作。
2.方法重載
PHP5中有一個魔術方法__call,該方法可以用於實現方法的重載。__call方法必須要有兩個參數。第一個參數包含被調用的方法名稱,第二個參數包含傳遞給該方法的參數數組。__call方法在類中的方法被訪問時被調用。
3.訪問類的屬性
通常情況下,從類的外部直接存取類的屬性是不建議使用的方法。這時可以使用__get和__set方法來檢查和設定屬性的值,這樣就可以實現封裝性。
4.字串轉換
如果要輸出對象,可以在類中定義一個__toString方法,在方法中返回一個可輸出的字串。
5.自動載入對象
__autoload方法用於自動載入對象,它不是一個類方法,而是一個單獨的函數。如果指令碼中定義了__autoload函數,當時用new關鍵字執行個體化一個沒有聲明的類時,這個類的名字將作為參數傳遞給__autoload函數,__autoload函數根據參數自動包含有類的檔案,並載入類檔案中的同名類。
6.對象序列化
對象序列化是指將一個對象轉換成位元組流的形式,將序列化後的對象在一個檔案或網路上傳輸,然後再還原序列化還原為原資料。對象序列化使用serialize()函數,還原序列化使用unserialize()函數。在對象序列化時,如果存在魔術方法__sleep,PHP會調用__sleep方法,主要用於清楚如資料提交、關閉資料庫連結等工作,並返回一個數組,該數組包含需要序列化的所有變數;在還原序列化一個對象後,PHP會調用__wakeup方法,主要用於重建對象序列化時丟失的資源。這兩個魔術方法都不接收參數。
十、執行個體類型的判斷
當系統很大時,往往需要判斷某個對象是否是某個類建立的。這時可以使用instanceof關鍵字來實現。instanceof關鍵字可以檢查一個對象的類型,判斷一個對象是否是特定類的執行個體,是否繼承於某個類或實現某個介面。用法如下:
$var instanceof class_name;
如果變數$var是類class_name建立的對象,則返回TRUE,否則返回FALSE。
本文出自 “遊騎兵” 部落格,請務必保留此出處http://ccnupxz.blog.51cto.com/8803964/1840641
PHP中關於物件導向程式設計的相關簡介