搜索
熱搜: 活動 交友 discuz
查看: 5753|回復: 0
打印 上一主題 下一主題

[PHP] [PHP]物件導向程式設計入門與實作 (for PHP)

[複製鏈接]
跳轉到指定樓層
1#
發表於 2013-8-28 13:57:13 | 只看該作者 回帖獎勵 |正序瀏覽 |閱讀模式
本篇文章針對PHP做物件導向程式設計的教學,包含實作範例。

首先建立一個類別名稱,並用中括號{}規範其範圍,建立完類別MyClass後,新增一個變數$obj將類別實例化, 再將變數用var_dump來檢視其內容,
  1. <?php     
  2. class MyClass  
  3. {  
  4.     // 類別屬性及方法在此
  5. }  
  6.   $obj = new MyClass;
  7.   var_dump($obj);  
  8. ?>
複製代碼
結果會顯示, 新視窗看結果, 耶!第一個物件導向的例子完成了!
  1. object(MyClass)#1 (0) { }
複製代碼

定義類別屬性

要新增資料到類別裡, 屬性及特定類別變數都會用到, 就像一般變數一樣, 只是會依賴著物件,public會決定此變數的公開程度, echo時,利用箭頭符號->來引用(調用)物件的方法或屬性
  1. <?php  
  2.    
  3. class MyClass  
  4. {  
  5.     public $prop1 = "我是類別屬性!";  
  6. }  
  7.    
  8. $obj = new MyClass;  
  9.    echo $obj->prop1; // 輸出屬性
  10.    
  11. ?>
複製代碼
結果會顯示, 新視窗看結果
  1. 我是類別屬性!
複製代碼

定義類別方法

方法是特定類別的函式,定義了物件活動的呈現方式, 範例中新增了兩個方法"設定屬性"與"取得屬性",來存取$prop1, OOP允許物件使用$this來引用他自己, 在方法裡使用$this就好比在類別外面的物件名稱($obj)一樣, 此範例會先取得屬性值, 接著給他新值, 再echo一次觀察變化…
  1. <?php  

  2. class MyClass  
  3. {  
  4.     public $prop1 = "我是類別屬性!";  
  5.    
  6.     public function setProperty($newval)  
  7.     {  
  8.         $this->prop1 = $newval;  
  9.     }  
  10.    
  11.     public function getProperty()  
  12.     {  
  13.         return $this->prop1 . "<br />";  
  14.     }  
  15. }  
  16. $obj = new MyClass;  
  17. echo $obj->getProperty(); // 取得屬性值

  18. $obj->setProperty("我是新的類別屬性值!"); // 設定新值  
  19. echo $obj->getProperty(); // 再顯示一次屬性值  
  20.    
  21. ?>
複製代碼
結果會顯示, 新視窗看結果, 當然可以新增$obj2,$obj3,$obj4, OOP方便讓物件可以維持個別的實體。
  1. 我是類別屬性!
  2. 我是新的類別屬性值!
複製代碼

Magic Method

PHP的一系列Magic Method包含 __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __set_state 和 __clone, 以兩行底線做區別, PHP網站的中文翻做魔術方法有點詭異。
使用建構子與解構子

Constructor以及Destructor, 一個類別往往有許多初始化時要做的事情, 因此PHP提供 __construct方法, 讓類別被實例化時, 就會自動執行!
  1. <?php  
  2. class MyClass  
  3. {  
  4.     public $prop1 = "我是類別屬性!";  
  5.     public function __construct()  
  6.     {  
  7.         echo '類別 "', __CLASS__, '" 初始化!<br />';
  8.     }
  9.     public function __destruct()
  10.     {
  11.         echo '類別 "', __CLASS__, '" 被釋放.<br />';  
  12.     }  
  13.     public function setProperty($newval)  
  14.     {  
  15.         $this->prop1 = $newval;  
  16.     }  
  17.    
  18.     public function getProperty()  
  19.     {  
  20.         return $this->prop1 . "<br />";  
  21.     }  
  22. }  
  23. $obj = new MyClass;  
  24. echo $obj->getProperty(); // 取得屬性值

  25. unset($obj);  // 釋放物件  
  26.    
  27. echo "到最底端了!<br />";

  28. ?>
複製代碼
當類別被實例化時, 會執行__construct, __CLASS__ 會回傳被呼叫建構子所屬的類別名稱; 當程式碼到底端時, __desturct會釋放所有資源, 也可以使用unset提前觸發! 結果會顯示, 新視窗看結果。
  1. 類別 "MyClass" 初始化!
  2. 我是類別屬性!
  3. 類別 "MyClass" 被釋放.
  4. 到最底端了!
複製代碼

轉換成字串

如果新增了一個物件$obj之後, 直接echo $obj; 會發生fatal error錯誤訊息!告知類別無法轉換成字串,所以透過__toString方法, 就可以指定echo直接輸出的內容。
  1. Catchable fatal error: Object of class MyClass could not be converted to string in /OOP_Magc_Method_String.php on line xx
複製代碼
  1. <?php  
  2. class MyClass  
  3. {  
  4.     public $prop1 = "我是類別屬性!";  
  5.     public function __construct()  
  6.     {  
  7.         echo '類別 "', __CLASS__, '" 初始化!<br />';
  8.     }
  9.     public function __destruct()
  10.     {
  11.         echo '類別 "', __CLASS__, '" 被釋放.<br />';  
  12.     }  
  13.     public function __toString()  
  14.     {  
  15.         echo "使用 toString 方法: ";  
  16.         return $this->getProperty();  
  17.     }
  18.     public function setProperty($newval)  
  19.     {  
  20.         $this->prop1 = $newval;  
  21.     }  
  22.     public function getProperty()  
  23.     {  
  24.         return $this->prop1 . "<br />";  
  25.     }  
  26. }  
  27. $obj = new MyClass;  
  28. echo $obj->getProperty(); // 取得屬性值
  29. echo $obj; //直接輸出類別
  30. unset($obj);  // 釋放物件  
  31. echo "到最底端了!<br />";
  32. ?>
複製代碼
範例中__toString() return了getProperty的結果, 新視窗看結果
  1. 類別 "MyClass" 初始化!
  2. 我是類別屬性!
  3. 使用 toString 方法: 我是類別屬性!
  4. 類別 "MyClass" 被釋放.
  5. 到最底端了!
複製代碼

使用類別繼承

使用extend關鍵字, 就可以將一個類別的方法及屬性遺傳給令一個類別(遺傳的意思好像比較正確), 範例新增了一個MyNewClass類別繼承自MyClass,同樣的方法再寫一次就會覆寫. 因此覆寫了__construct()方法, 繼承了__toString(), setPreperty(), getProperty(), 新增了newMethod()方法; 為了保留父類別已經被覆蓋的方法, 可使用parent關鍵字加上兩個冒號::(scope resolution operator)來取得。
  1. <?php  
  2. class MyClass  
  3. {  
  4.     public $prop1 = "我是類別屬性!";  
  5.     public function __construct()  
  6.     {  
  7.         echo '類別 "', __CLASS__, '" 初始化!<br />';
  8.     }
  9.     public function __destruct()
  10.     {
  11.         echo '類別 "', __CLASS__, '" 被釋放.<br />';  
  12.     }  
  13.     public function __toString()  
  14.     {  
  15.         echo "使用 toString 方法: ";  
  16.         return $this->getProperty();  
  17.     }
  18.     public function setProperty($newval)  
  19.     {  
  20.         $this->prop1 = $newval;  
  21.     }  
  22.     public function getProperty()  
  23.     {  
  24.         return $this->prop1 . "<br />";  
  25.     }  
  26. }  
  27. class MyNewClass extends MyClass  
  28. {  
  29.     public function __construct()  
  30.     {  
  31.         parent::__construct(); // 呼叫父類別的建構子
  32.         echo "新建構子 " . __CLASS__ . ".<br />";  
  33.     }  
  34.     public function newMethod()  
  35.     {  
  36.         echo "新方法 " . __CLASS__ . ".<br />";  
  37.     }  
  38. }
  39. $newobj = new MyNewClass;  
  40. echo $newobj->newMethod(); //輸出字串
  41. echo $newobj->getProperty(); //使用父類別的方法
  42. ?>  
複製代碼
範例中的結果, 新視窗看結果
  1. 類別 "MyClass" 初始化!
  2. 新建構子 MyNewClass.
  3. 新方法 MyNewClass.
  4. 我是類別屬性!
  5. 類別 "MyClass" 被釋放.
複製代碼

分配方法與屬性的可見度

為了要控制許多物件, 方法與屬性都被指定了可以存取的程度, 包含public、protected、private三種關鍵字, 除了本身的可見度以外, 方法與屬性也可宣告為Static, 不用透過類別實例化就可以存取。
1.Public – 所有的屬性與方法可以再任何地方被存取,包含內部class與外部呼叫。
2.Protected – 受保護的屬性與方法只能被他自己以及衍生類別存取。
  1. <?php  
  2. class MyClass  
  3. {  
  4.     public $prop1 = "我是類別屬性!";  
  5.     public function __construct()  
  6.     {  
  7.         echo '類別 "', __CLASS__, '" 初始化!<br />';
  8.     }
  9.     public function __destruct()
  10.     {
  11.         echo '類別 "', __CLASS__, '" 被釋放.<br />';  
  12.     }  
  13.     public function __toString()  
  14.     {  
  15.         echo "使用 toString 方法: ";  
  16.         return $this->getProperty();  
  17.     }
  18.     public function setProperty($newval)  
  19.     {  
  20.         $this->prop1 = $newval;  
  21.     }
  22.     protected function getProperty()  
  23.     {  
  24.         return $this->prop1 . "<br />";  
  25.     }  
  26. }  
  27. class MyNewClass extends MyClass  
  28. {  
  29.     public function __construct()  
  30.     {  
  31.         parent::__construct(); // 呼叫父類別的建構子
  32.         echo "新建構子 " . __CLASS__ . ".<br />";  
  33.     }  
  34.        public function newMethod()  
  35.     {  
  36.         echo "新方法 " . __CLASS__ . ".<br />";  
  37.     }  
  38.     public function callProtected()  
  39.     {  
  40.         return $this->getProperty();  
  41.     }
  42. }
  43. $newobj = new MyNewClass;  
  44. echo $newobj->callProtected(); //從一個public方法內呼叫protected的方法
  45. ?>
複製代碼
範例中MyNewClass先新增一個方法callProtected()去取得父類別的getProperty(),結果如下新視窗看結果
  1. 類別 "MyClass" 初始化!
  2. 新建構子 MyNewClass.
  3. 我是類別屬性!類別 "MyClass" 被釋放.
複製代碼
3.Private – 私有的屬性與方法只定義它的類別可存取,就算是衍生類別也不行。
4.Static – 不需要透過第一次類別實例化,透過類別名稱、雙帽號、屬性或方法就能存取。
  1. <?php  
  2. class MyClass  
  3. {  
  4.     public $prop1 = "我是類別屬性!";  
  5.     public static $count = 0;
  6.     public function __construct()  
  7.     {  
  8.         echo '類別 "', __CLASS__, '" 初始化!<br />';
  9.     }
  10.     public function __destruct()
  11.     {
  12.         echo '類別 "', __CLASS__, '" 被釋放.<br />';  
  13.     }  
  14.     public function __toString()  
  15.     {  
  16.         echo "使用 toString 方法: ";  
  17.         return $this->getProperty();  
  18.     }
  19.     public function setProperty($newval)  
  20.     {  
  21.         $this->prop1 = $newval;  
  22.     }
  23.     protected function getProperty()  
  24.     {  
  25.         return $this->prop1 . "<br />";  
  26.     }
  27.     public static function plusOne()  
  28.     {  
  29.         return "The count is " . ++self::$count . ".<br />";  
  30.     }  
  31. }  
  32. class MyNewClass extends MyClass  
  33. {  
  34.     public function __construct()  
  35.     {  
  36.         parent::__construct(); // 呼叫父類別的建構子
  37.         echo "新建構子 " . __CLASS__ . ".<br />";  
  38.     }  
  39.     public function newMethod()  
  40.     {  
  41.         echo "新方法 " . __CLASS__ . ".<br />";  
  42.     }  
  43.     public function callProtected()  
  44.     {  
  45.         return $this->getProperty();  
  46.     }
  47. }
  48. do
  49. {  
  50.     // 不實例化就直接呼叫 plusOne()  
  51.     echo MyClass::plusOne();  
  52. } while ( MyClass::$count < 10 );
  53. ?>
複製代碼
範例中有個迴圈會呼叫plusOne()進行計數, 直到$count小於10, 沒有實例化就直接呼叫, 結果如下新視窗看結果
  1. The count is 1.
  2. The count is 2.
  3. The count is 3.
  4. The count is 4.
  5. The count is 5.
  6. The count is 6.
  7. The count is 7.
  8. The count is 8.
  9. The count is 9.
  10. The count is 10.
複製代碼


最後這篇文章還比較並舉例Procedural和OOP的不同,統整了物件導向程式設計的優點: 
1.容易實作 
2.方便組織 
3.更好維護
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

本論壇為非營利之網路平台,所有文章內容均為網友自行發表,不代表論壇立場!若涉及侵權、違法等情事,請告知版主處理。


Page Rank Check

廣告刊登  |   交換連結  |   贊助我們  |   服務條款  |   免責聲明  |   客服中心  |   中央分站

手機版|中央論壇

GMT+8, 2026-5-22 02:50 , Processed in 0.035208 second(s), 17 queries .

Powered by Discuz!

© 2005-2015 Copyrights. Set by YIDAS

快速回復 返回頂部 返回列表