對象複製
對象在預設情況下都是按引用傳遞的,如果需要複製一個對象,將對象的值進行一個完整的cp,需要使用clone方法
class Corporate_Drone{ private $employeeid; private $tiecolor; function setEmployeeID($employeeid) { $this->employeeid = $employeeid; } function getEmployeeID() { return $this->employeeid; } function setTieColor($tiecolor) { $this->tiecolor = $tiecolor; } function getTieColor(){ return $this->tiecolor; }}$drone1 = new Corporate_Drone();$drone1->setEmployeeID("12345");$drone1->setTieColor("red");$drone2 = clone $drone1; //這裡複製執行個體$drone1,因為$drone1已經set過屬性了,所以clone得時候一併複製了,$drone2->setEmployeeID("67890"); //然後這裡複製後的$drone2 set自己的屬性echo "Drone1 employeeID is ".$drone1->getEmployeeID()."\n";echo "Drone1 tie color is ".$drone1->getTieColor()."\n";echo "Drone2 employeeid is ".$drone2->getEmployeeID()."\n";echo "Drone2 tie color is ".$drone2->getTieColor()."\n";----Drone1 employeeID is 12345Drone1 tie color is red Drone2 employeeid is 67890 //這裡被修改了,但是下面的color依然是執行個體$drone1的屬性值Drone2 tie color is red
上面是複製一整個對象的,可以用__clone方法來調整對象複製的行為,此方法只複製操作期間執行
class Corporate_Drone{ private $employeeid; private $tiecolor; function setEmployeeID($employeeid) { $this->employeeid = $employeeid; } function getEmployeeID() { return $this->employeeid; } function setTieColor($tiecolor) { $this->tiecolor = $tiecolor; } function getTieColor(){ return $this->tiecolor; } function __clone() { $this->tiecolor = "blue"; //這裡是指這個__clone方法會在複製期間修改顏色tiecolor }}$drone1 = new Corporate_Drone();$drone1->setEmployeeID("12345");$drone1->setTieColor("red");$drone2 = clone $drone1; //這裡複製執行個體$drone1,因為$drone1已經set過屬性了,所以clone得時候一併複製了,$drone2->setEmployeeID("67890"); //然後這裡複製後的$drone2 set自己的屬性echo "Drone1 employeeID is ".$drone1->getEmployeeID()."\n";echo "Drone1 tie color is ".$drone1->getTieColor()."\n";echo "Drone2 employeeid is ".$drone2->getEmployeeID()."\n";echo "Drone2 tie color is ".$drone2->getTieColor()."\n";----Drone1 employeeID is 12345Drone1 tie color is redDrone2 employeeid is 67890Drone2 tie color is blue //看這裡結果,顏色被改變了。
類繼承
繼承就是父親和兒子的關係,兒子可以使用父親的跑車,也可以自己買單車的同時邊開父親的跑車,畢竟都是他們家的。
class Employee{ private $name; function setName($name) { if ($name == "") echo "Name connot be blank!"; else $this->name = $name; } function getName() { return "My name is ".$this->name."\n"; }}class Executive extends Employee{ //這裡用extends繼承,Executive 繼承了Employee的類的所有屬性和方法 function pillageCompany() { //這裡Executive也有自己的方法 echo "Im selling company assets to finance my yacht!"; }}$exec = new Executive();$exec->setName("richard"); //因為繼承了Employee父類,所以可以setnameecho $exec->getName()."\n"; //同上$exec->pillageCompany(); //也可以使用自己的方法----My name is richardIm selling company assets to finance my yacht!
繼承和建構函式
如果父類有建構函式,而且子類沒有建構函式,那麼在子類執行個體化得時候是會執行父類的建構函式的,如果父類和子類同時都有建構函式的話,那麼當子類執行個體化的時候,只會執行子類的建構函式,除非使用
parent顯式調用父類建構函式,又或者直接調用父類的建構函式 classname::__construct()
繼承與延遲靜態繫結
有一種情況,一個父方法要與靜態類屬性互動,但這些靜態類屬性可能在子類被覆蓋,那麼怎麼定義static靜態類的範圍呢,之前一直也沒有說這個情況,因為靜態類定義本身就是僅在局部函數域中存在,但當程式執行離開此範圍時,其值並不丟失。
這種情況在php5.3後被解決。
class Employee{ public static $favSport = "Football"; //在class employee中的靜態變數$favSport public static function watchTV() { echo "Watching ".self::$favSport; //這裡調用了class employee的靜態變數 }}class Executive extends Employee{ public static $favSport = "polo"; //在class Excutive的靜態變數$favSport,由於Ex是繼承了Em的,所以理當是能夠覆蓋變數的,但是因為執行的是靜態方法watchTV,對此給出的解釋是,self關鍵字會在編譯的時候而非運行時確定其範圍,因此,結果是Football public static function watchTV() { //如果通過重寫watchTV函數,重新定義使用的static的變數,就可以重新定義static的範圍,從而實現需要的覆蓋效果 echo "Watching ".static::$favSport; }}echo Executive::watchTV();
介面和抽象類別
介面定義了實現某種服務的一般規範,聲明了必須的函數和常量,但是不指定如何?。關鍵是要建立必須實現的一組一般原則,只有滿足了這些原則才能說實現了這個介面。
抽象類別是不能被執行個體化的類,只能作為由其他類繼承的基類,例如一個名為media的類,他是用於描述各種公開出版的共同性質,因為media不表示真實的實體,而是一些相似實體的泛化表示,所以不執行個體化,這樣就需要聲明為抽象類別,然後再由各種的派生的Media類繼承此抽象類別
什麼時候用介面,什麼時候用抽象類別
- 如果要建立一個模型,這個模型將由一些緊密相關的對象引用,就可以採用抽象類別,如果要建立將由一些不想關的對象採用的功能,應該用介面。
- 如果必須從多個來源繼承行為,就是用介面。
- 如果知道所有類都會共用一個公用的行為實現,就使用抽象類別,並在其中實現行為。介面無法實現。
命名空間
什麼是命名空間?從廣義上來說,命名空間是一種封裝事物的方法。在很多地方都可以見到這種抽象概念。例如,在作業系統中目錄用來將相關檔案分組,對於目錄中的檔案來說,它就扮演了命名空間的角色。具體舉個例子,檔案 foo.txt 可以同時在目錄/home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt 檔案。另外,在目錄 /home/greg 外訪問 foo.txt 檔案時,我們必須將目錄名以及目錄分隔字元放在檔案名稱之前得到 /home/greg/foo.txt。這個原理應用到程式設計領域就是命名空間的概念。
< ?phpnamespace Foo\Bar;include 'file1.php';const FOO = 2;function foo() {}class foo{ static function staticmethod() {}}/* 非限定名稱 */foo(); // 解析為 Foo\Bar\foo resolves to function Foo\Bar\foofoo::staticmethod(); // 解析為類 Foo\Bar\foo的靜態方法staticmethod。resolves to class Foo\Bar\foo, method staticmethodecho FOO; // resolves to constant Foo\Bar\FOO/* 限定名稱 */subnamespace\foo(); // 解析為函數 Foo\Bar\subnamespace\foosubnamespace\foo::staticmethod(); // 解析為類 Foo\Bar\subnamespace\foo, // 以及類的方法 staticmethodecho subnamespace\FOO; // 解析為常量 Foo\Bar\subnamespace\FOO/* 完全限定名稱 */\Foo\Bar\foo(); // 解析為函數 Foo\Bar\foo\Foo\Bar\foo::staticmethod(); // 解析為類 Foo\Bar\foo, 以及類的方法 staticmethodecho \Foo\Bar\FOO; // 解析為常量 Foo\Bar\FOO?>
本文由 PeterYuan 創作,採用 署名-非商業性使用 2.5 中國大陸 進行許可。 轉載、引用前需聯絡作者,並署名作者且註明文章出處。神一樣的少年 » 第三章(進階oop)-《php和mysql web開發》《php與mysql程式設計》齊讀