您好,登錄后才能下訂單哦!
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關鍵字。例如:
<?php interface 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。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。