(OOP)來開發。物件導向開發相對於面向過程有很多優點:
維護簡單 模組化是物件導向編程中的一個特徵。實體被表示為類和同一名字空間中具有相同功能的類,我們可以在名字空間中添加一個類而不會影響該名字空間的其他成員。
可擴充性 物件導向編程從本質上支援擴充性。如果有一個具有某種功能的類,就可以很快地擴充這個類,建立一個具有擴充的功能的類。
代碼重用 由於功能是被封裝在類中的,並且類是作為一個獨立實體而存在的,提供一個類庫就非常簡單了。
它比較適合多人合作來開發項目,所以現在很多大中型網站都選擇了用OOP來開發。
下面我來來介紹物件導向編程
類與屬性和方法
PHP中定義類文法格式:
| 代碼如下 |
複製代碼 |
class classname [可選屬性]{ public $property [=value];… //用public聲明一個公用標識 然後給予一個變數 變數也可以賦值 function functionname ( args ){ //類的方法裡的成員函數 代碼} … //類的方法(成員函數) } |
產生對象(類的執行個體化): $對象名=new classname( );
使用對象的屬性
在一個類中,可以訪問一個特殊指標$this當在該類中通過一個操作設定或訪問該變數時,使用$this->name來引用.
| 代碼如下 |
複製代碼 |
class person{ function _ _destruct( ) { echo "bye bye !“; } } $a=new person(); |
1.final
final:php5新增一個final關鍵字。如果父類中的方法被聲明為final,則子類無法覆蓋該方法;如果一個類被聲明final,則不能被繼承。
| 代碼如下 |
複製代碼 |
class BaseClass{ public function test(){ ehco "test"; } final public function moreTest(){ echo "moretest"; } } class ChildClass extends BaseClass{ public function moreTest(){ echo "moretest"; } } // 產生 Fatal error: Cannot override final method BaseClass::moretest()
|
2.__toString(建議用PHP5.2或者更高版本)
| 代碼如下 |
複製代碼 |
class Person{ protected $name; protected $email; public function setName($name){ $this->name = $name; } public function setEmail($email){ $this->email = $email; } public function __toString(){ return "$this->name <$this->email>"; } } $rasums = new Person; $rasums->setName('test'); $rasums->setEmail('test@qq.com'); print $rasums; |
3.介面和抽象類別
介面的作用:你想要保證一個類按照特定的名稱、可見度和原型實現一個或多個方法。
介面的要求:
類中全部為抽象方法
抽象方法錢不用加abstract
介面抽象方法屬性為public
成員屬性必須為常量
例:
| 代碼如下 |
複製代碼 |
interface ChildTest{ public function childTest(); } class FathTest implements ChildTest1,ChildTest2{ public function childTest(){ echo 1; } ………… }
|
抽象的作用: 其實抽象類別和介面類有一部分很像,記得在哪裡看見這樣一句話,抽象類別就把類像的部分抽出來,這句看上去很搞笑,其實它說出了抽象類別的真理,抽象類別的作用 是,當你發現你的很多類裡面用很多方法你不斷的在重複寫,那你就可以考慮使用抽象類別了,你可能會說“我不是可以重寫一個類每個公用類我個執行個體化一個這個公 共類,調用相同的方法就可以了”,這裡是可以,實際上抽象類別做的工作也就是這個,不過他省去了你執行個體化的這個步驟,讓你就像直接調用本類方法一樣方便,而 且你還可以重載這個方法。
抽象的要求:
類中至少有一個抽象方法
抽象方法錢必須加abstract
例:
| 代碼如下 |
複製代碼 |
abstract class Database{ abstract public function connect(); abstract public function query(); abstract public function fetch(); abstract public function close(); }
|
註:抽象方法不能定義為私人方法、不能定義為最終方法,因為它們需要被繼承。
4.傳遞對象引用
php4:所有“=”都是建立一個副本
php5:除了對象外,其他“=”進行賦值時,都是建立一個副本;而對象則是引用
5.複製對象
一、
彙總類:
__call方法簡介:
當用戶端代碼用類中未定義的方法時,__call會被調用。
__call()接受兩個參數,一個是方法名稱,另一個是傳遞給要調用方法的所有參數(包括數組)
__call()方法返回的任何值都會返回給客戶,將好像調用方式真實存在一樣
例:
| 代碼如下 |
複製代碼 |
class Address{ protected $city; protected $country; public function setCity($city){$this->city = $city;} public function getCity(){return $this->city;} public function setCountry($country){$this->country = $country;} public function getCountry(){return $this->country;} } class Person{ protected $name; protected $address; //淺複製 public function __construct(){ $this->address = new Address; } public function setName($name){ $this->name = $name; } public function getName(){ return $this->name; } public function __call($method,$arguments){ if(method_exists($this->address,$method)){ return call_user_func_array(array($this->address,$method),$arguments); } } //深複製 public function __clone(){ $this->address = clone $this->address; } } $test1 = new Person; $test2 = clone $test1; $test1->setName('testname1'); $test1->setCity('testcity1'); $test2->setName('testname2'); $test2->setCity('testcity2'); echo $test1->getName().'-'.$test1->getCity()."n"; echo $test2->getName().'-'.$test2->getCity()."n"; //testname1-testcity2 //testname2-testcity2 |
6.重要屬性訪問(__set __get __isset __unset) __isset __unset5.1之後才有用
作用:攔截對屬性的需求,為了提高分離的程度,還要實現__isset()和__unset(),以便當我們用isset來檢測屬性或者unset()來刪除屬性,來保證類的行為正確
例:
| 代碼如下 |
複製代碼 |
class Person{ protected $__data = array('email','test'); public function __get($property){ if(isset($this->__data[$property])){ return $this->__data[$property]; }else{ return false; } } public function __set($property,$value){ if(isset($this->__data[$property])){ return $this->__data[$property] = $value; }else{ return false; } } public function __isset($property){ if(isset($this->__data[$property])){ return true; }else{ return false; } } public function __unset($property){ if(isset($this->__data[$property])){ return unset($this->__data[$property]); }else{ return false; } } } $test = new Person; $test->email= 'test'; var_dump($test->email); |
注意:
這兩個方法只會捕捉缺少的屬性,如果你為你的類定義了一個屬性,那麼當訪問這個屬性時php不會調用__get()和__set();
這兩個方法完全破壞了任何屬性繼承的想法。如果父物件中有個 __get()方法,而你在子類中又實現了自己的__get()方法,那麼你的對象不會正確的執行,因為父類的__get()方法永遠不會被調用,當然可以用parent::__get()解決
缺點:
速度相對較慢
使用魔術訪問器方法就不可能在使用反射類,如phpdocumentor這類的工具將代碼自動文檔化
不能將其用於靜態屬性