http://blog.csdn.net/hj960511/article/details/51479755php
1、PHP面向對象的簡單列子
以人爲列子:html
<?php header("Content-type: text/html; charset=utf-8"); class person{ //下面是人的成員屬性 var $name; //人的名字 var $sex; //人的性別 var $age; //人的年齡 //定義一個構造方法參數爲姓名$name,性別$sex和年齡$age function __construct($name,$sex,$age){ //經過構造方法傳進來的$name給成員屬性$this->name賦初始值 $this->name=$name; //經過構造方法傳進來的$sex給成員屬性$this->sex賦初始值 $this->sex=$sex; //經過構造方法傳進來的$age給成員屬性$this->age賦初始值 $this->age="$age"; } //下面是人的成員方法 function say() //這我的能夠說話的方法 { echo "個人名字叫:".$this->name."性別;".$this->sex."個人年齡是:".$this->age."<br>"; } function run() //這我的能夠走路的方法 { echo "這我的在走路"; } //這是一個析構函數,在對象銷燬前調用 function __destruct() { echo "再見".$this->name."<br>"; } } //經過構造方法建立3個對象$p1,$p2,$p3,分別傳入三個不一樣的實參爲姓名性別和年齡 $p1=new person("小明","男",20); $p2=new person("熊","女",30); $p3=new person("向日葵","男",25); $p1->say(); $p2->say(); $p3->say(); //下面訪問3個對象的說話方式$p1->say();$p2->say();$p3->say(); ?>
2、php面向對象的幾個步驟
第一類的定義:mysql
<?php Class myobject{ //…… } ?>
第二成員方法:web
<?php classmyobject{ function getobjectname($name){ echo "商品名稱爲:".$name; } } ?>
第三類的實例化:sql
<?php class myobject{ function getobjectname($name){ echo "商品名稱爲:".$name; } } $c_book=new myobject(); //實例化對象 echo $c_book->getobjectname("計算機圖書"); //調用getbookname()方法 ?>
第四成員變量:數據庫
<?php class myobject{ public $object_name; functionsetobjectname($name){ $this->object_name=$name; } functiongetobjectname(){ return$this->object_name; } } $c_book=new myobject(); $c_book->setobjectname("計算機圖書"); echo $c_book->object_name."<br>"; echo $c_book->getobjectname(); ?>
第五常量類:
既然有變量,固然也會有常量了。常量就是不會改變的量,是一個恆值。衆所周知的一個常量就是圓周率Pi。定義常量使用關鍵字const如:
ConstPI=3.14159;
例:數組
<?php class myobject{ const book_type="計算機圖書"; //聲明常量book_type public $object_name; //聲明變量 functionsetobjectname($name){ //聲明方法setobjectname() $this->object_name=$name; //設置成員的變量值 } functiongetobjectname(){ //聲明方法getobject() return$this->object_name; } } $c_book=new myobject(); //實例化對象 $c_book->setobjectname("PHP的類"); //調用方法setobjectname echo myobject::book_type."<br>"; //輸出常量的值 echo $c_book->getobjectname(); //調用方法getobjectname ?>
第六面向對象類的構造方法markdown
<?php class myobject{ public $object_name; //商品名稱 public $object_price; //商品價格 public $object_num; //商品數量 public $object_agio; //商品折扣 ………… } ?>
聲明一個myobject類的對象,並對這個類的一些成員變量賦初值。代碼以下:dom
<?php class myobject{ public $object_name; public $object_price; public $object_num; public $object_agio; functiongetobjectname(){ return$this->object_name; return$this->object_price; return $this->object_num; return $this->object_agio; } } $dress=new myobject(); $dress->object_name="western-style clothes"; $dress->object_price=1500; $dress->object_num=5; $dress->object_agio=8; echo $dress->getobjectname(); ?> Void__construect([mixed args,[……]])
注意:函數中的__是兩條下劃線,不是一條。
實例2:函數
<?php class myobject{ public $object_name; public $object_price; public $object_num; public $object_agio; function__construct($name,$price,$num,$agio){ //經過參數給成員變量賦值 $this->object_name=$name; $this->object_price=$price; $this->object_num=$num; $this->object_agio=$agio; } function setobjectname($name){ $this->object_name=$name; } function getobjectname1(){ return $this->object_name; } function getobjectname2(){ return $this->object_price; } } $c_book=new myobject("western-styleclothes",1500,5,8); echo $c_book->getobjectname1(); echo "<br>"; echo $c_book->getobjectname2(); ?>
第七析構方法:
概念
析構方法的做用和構造方法正好相反,是對象被銷燬時被調用的,做用是釋放內存。析構方法的格式爲:
Void__destruct(void)
例:
<?php class myobject{ public $object_name; public $object_price; public $object_num; public $object_agio; function__construct($name,$price,$num,$agio){ //經過參數給成員變量賦值 $this->object_name=$name; $this->object_price=$price; $this->object_num=$num; $this->object_agio=$agio; } function setobjectname($name){ $this->object_name=$name; } function getobjectname1(){ return $this->object_name; } function getobjectname2(){ return $this->object_price; } function __destruct(){ echo "<p><b>對象被銷燬,調用析構函數。</b></p>"; } } $c_book=new myobject("western-styleclothes",1500,5,8); echo $c_book->getobjectname1(); echo "<br>"; echo $c_book->getobjectname2(); unset($c_book); ?>
PHP使用的是一種「垃圾回收」機制,自動清除再也不使用的對象,釋放內存。就是說即便不使用unset函數,析構方法也會自動被調用,這裏只是明確一下析構函數在什麼時候被調用。通常狀況下是不須要手動建立析構方法的。
<?php class myobject{ public $object_name; public $object_price; public $object_num; public $object_agio; function __construct($name,$price,$num,$agio){ //經過參數給成員變量賦值 $this->object_name=$name; $this->object_price=$price; $this->object_num=$num; $this->object_agio=$agio; } function setobjectname($name){ $this->object_name=$name; } function getobjectname1(){ return$this->object_name; } function getobjectname2(){ return $this->object_price; } function __destruct(){ echo"<p><b>對象被銷燬,調用析構函數。</b></p>"; } } $c_book=new myobject("western-styleclothes",1500,5,8); echo $c_book->getobjectname1(); echo "<br>"; echo $c_book->getobjectname2(); ?>
第八繼承和多狀態的實現
Class subclass extends superclass{ …… }
說明:subclass爲子類的名稱,superclass爲父類名稱。
例:
<?php class myobject{ public $object_name; public $object_price; public $object_num; public $object_agio; function__construct($name,$price,$num,$agio){ //經過參數給成員變量賦值 $this->object_name=$name; $this->object_price=$price; $this->object_num=$num; $this->object_agio=$agio; } function showme(){ echo "這句話會輸出嗎?答案是不會。"; } } class book extends myobject{ public $book_type; function__construct($type,$num){ $this->book_type=$type; $this->object_num=$num; } functionshowme(){ //重寫父類中的showme()方法。 return "本次新進".$this->book_type."圖書".$this->object_num."本"."<br>"; } } class elec extends myobject{ function showme(){ //重寫父類中的showme()方法 return "熱賣商品:".$this->object_name."<br>"."原 價:".$this->object_price."<br>"."特 價".$this->object_price*$this->object_agio; } } $c_book=new book("計算機類",1000); //聲明一個book子類對象。 $h_elec=new elec("待機王XX系列",1200,3,0.8); //聲明一個elec子類對象。 echo$c_book->showme()."<br>"; //輸出book子類的showme()方法 echo $h_elec->showme(); //輸出elec子類的是showme()方法 ?>
子類繼承了父類的全部成員變量和方法,包括構造函數。這就是繼承的實現。
當子類被建立時,PHP會先在子類中查找構造方法。若是子類有本身的構造方法,PHP會先調用子類中的方法,當子類中沒有時,PHP則會去調用父類中的構造方法。
兩個子類重寫了父類的方法showme(),因此兩個對象雖然調用的都是showme()方法,但返回的倒是兩段不一樣的信息。這就是多態性的實現。
第九和操做符的使用、this->
在 前面類的實例化中,對如何調用成員方法有了基本的瞭解,那就是用對象名加方法名,格式爲「對象名->方法名」。但在定義類時(如 myobject),根本沒法得知對象的名稱是什麼。這時若是調用類中的方法,就要用僞變量。this的意思就是自己,所 以$this->只能夠在類的內部使用。
例:
<?php classexample{ //建立類example function exam(){ //建立成員方法 if(isset($this)){ //判斷變量$this是否存在 echo "\$this的值爲:".get_class($this); //若是存在,輸出$this所屬類的名字 }else{ echo "$this未定義。"; } } } $class_name=newexample(); //實例化對象 $class_name->exam(); //調用方法exam() ?>
Get_class函數返回對象所屬類的名字,若是不是對象,則返回false。
二、操做符::
相比僞變量$this只能在類的內部使用,操做符::但是真正的強大。操做符::能夠在沒有聲明任何實例的狀況下訪問類中的成員方法和成員變量。使用::操做符的通用格式爲:
關鍵字::變量名/常量名/方法名
這裏的關鍵字分爲3種狀況:
Parent關鍵字:能夠調用父類中的成員變量、成員方法和常量。
Self關鍵字:能夠調用當前類中的靜態成員和常量。
類名:能夠調用本類中的變量、常量和方法。
例:
<?php class book{ const name="conputer"; //聲明常量name function __construct(){ //構造方法 echo "本月圖書類冠軍爲:".book::name."<br>"; //輸出默認值 } } class l_book extends book{ //book類的子類 const name="foreign language"; //聲明常量 function __construct(){ //子類的構造方法 parent::__construct(); //調用父類的構造方法 echo "本月圖書類冠軍爲:".self::name; //輸出本類中的默認值 } } $obj=new l_book(); ?>
說明:關於靜態方法(變量)的聲明及使用可參考如下內容。
第十公共、私有和保護
一、 public公共成員
顧名思義,就是能夠公開的、沒有必要隱藏的數據信息。能夠在程序的任何地點(類內、類外)被其餘的類和對象調用。子類能夠繼承和使用父類中全部的公共成員。
全部的變量都被聲明爲public,而全部的方法在默認的狀態下也是public。因此對變量
和方法的調用顯示得十分混亂。爲了解決這個問題,就須要使用第二個關鍵字:private。
二、 private私有成員
被private關鍵字修飾的變量和方法,只能在所屬類的內部被調用和修改,不能夠在類外被訪問。在子類中也不能夠。
例:
<?php class book{ private $name="computer"; public function setname($name){ $this->name=$name; } public function getname(){ return $this->name; } } class lbook extends book{ } $lbook=new lbook(); echo "正確操做私有變量的方法:"; $lbook->setname("PHP應用開發!"); echo $lbook->getname(); echo "直接操做私有變量的結果:"; echo book:name; ?>
對於成員方法,若是沒有寫關鍵字,那麼默認就是public。從本節開始,之後全部的方法及變量都會帶個關鍵字,這是一種良好的書寫習慣。
三、 protected保護成員
private 關鍵字能夠將數據徹底隱藏起來,除了在本類外,其餘地方都不能夠調用。子類也不能夠。但對於有些變量但願子類可以調用,但對另外的類來講,還要作到封裝。 這時,就可使用protected。被protected修改的類成員,能夠在類和子類中被調用,其餘地方則不能夠被調用。
例:
<?php class book{ protected $name="computer"; } class lbook extends book{ public function showme(){ echo "對於protected修飾的變量,在子類中是能夠直接調用的。如:\$name=".$this->name."<br>"; } } $lbook=new lbook(); $lbook->showme(); echo "但在其餘的地方是不能夠調用的,不然:"; $lbook->name="history"; ?>
第十一 PHP對象的高級應用
1. final關鍵字
final,中文含義是最終的、最後的。被final修飾過的類和方法就是「最終版本」;
若是有一個類的格式爲:
Final class class_name{ }
說明該類不能夠再被繼承,也不能再有子類。
若是有一個方法的格式爲:
Final function method_name();
說明該方法在子類中不能夠進行重寫,也不能夠被覆蓋。
例:
<?php final class myobject{ function __construct(){ echo "initialize object"; } } class mybook extends myobject{ static function exam(){ echo "you can't see me."; } } mybook::exam(); ?>
輸出的結果是:
Fatal error: Class mybookmay not inherit from final class (myobject) in C:\webserver\wwwroot\2.phpon line 19
Abstract class abstractname{ }
抽象類和普通類類似,都包含成員變量、成員方法。二者的區別在於,抽象類至少要包含一個抽象方法。抽象方法沒有方法體,其功能的實現只能在子類中完成。抽象方法也是使用abstract關鍵字修飾的。它的格式爲:
Abstractfunction abstractname();
注意:在抽象方法後面要有分號「;」
抽象類和抽象方法主要應用於複雜的層次關係中,這種層次關係要求每個子類都包含並重寫某些特定的方法。舉一個例子:中國的美食是多種多樣的,有吉菜、魯菜、川菜、粵菜等。每種菜系使用的都是煎、炒、炸等手法,只是在具體的步驟上,各有各的不一樣。若是把中國美食看成一個大類cate,下面的各大菜系就是cate的子類,而煎炒烹炸則是每一個類中都有的方法。每一個方法在子類中的實現都是不一樣的,在父類中沒法規定。爲了統一規範,不一樣子類的方法要有一個相同的方法名:decoct(煎)、stir_fry(炒)、cook(烹)、fry(炸)。
例:
<?php /* 抽象類myobject */ abstract class myobject{ //抽象方法servie abstract functionservice($getname,$price,$num); } //聲明抽象類的子類mybook class mybook extends myobject{ //實現抽象方法service function service($getname,$price,$num){ echo "您購買的商品是".$getname.",該商品的價格是:".$price."元"; echo "您購買的數量爲:".$num."本。"; echo "如發現缺頁、損壞、請在3日內更換。"; } } //聲明另外一個抽象類的子類mycomputer class mycomputer extends myobject{ //實現抽象方法service function service($getname,$price,$num){ echo "您購買的商品是:".$getname.",該商品的價格是:".$price."元。"; echo "您購買的數量爲:".$num."臺。"; echo "如發生非人爲質量問題,請在3個月內更換。"; } } $book=new mybook(); //實例化對象$book $computer=new mycomputer(); //實例化對象$computer $book->service("《PHP從入門到精通》",85,3); //調用$book對象的service方法 echo "<br />"; $computer->service("XX筆記本",8500,1); //調用computer對象的service方法 ?>
Interface interfacename{ Function interfacename1(); Function interfacename2(); ……………… }
注意:不要用public之外的關鍵字來修飾接口中的類成員,對於方法,不寫關鍵字也能夠。這是一個接口類自身的天性決定的。
子類是經過implements關鍵字來實現接口的,若是要實現多個接口,那麼每一個接口之間使用逗號「,」鏈接。並且全部未實現的方法須要在子類中所有實現,不然PHP將會出現錯誤。格式以下:
Class subclass implementsinterfacename1,interfacename2{ Function interfacename1(){ //功能實現 } Function interfacename2(){ //功能實現 } ………… }
例:本例首先聲明瞭兩個接口mpopedom和mpurview,接着聲明瞭兩個類member和manager,其中member類繼承了mpopedom接口;manager繼承了mpopedom和mpurview接口。分別實現各自的成員方法後,實例化兩個對象和manager。最後調用實現的方法。
<?php interface mpopedom{ function popedom(); } interface mpurview{ function purview(); } class member implements mpurview{ function purview(){ echo "會員擁有的權限"; } } class manager implements mpurview,mpopedom{ function purview(){ echo "管理員擁有會員的所有權限。"; } function popedom(){ echo "管理員還有會員沒有的權限。"; } } $member=new member(); $manager=new manager(); $member->purview(); echo "<br />"; $manager->purview(); $manager->popedom(); ?>
經過上面的實例能夠發現,抽象類和接口實現的功能十分類似。抽象類的優勢是能夠在抽象類中實現公共的方法,而接口則能夠實現多繼承。至於什麼時候使用抽象類和接口就要看具體實現了。
4. 克隆對象
(1)、克隆對象
在PHP4中,對象被看成普通的數據類型來使用。若是想引開對象,須要使用&來聲明,不然會按照PHP4的默認方式來按值傳遞對象。
例:本實例首先實例化一個myobject類的對象,book1的默認值是book,而後將對象使用普通數據類型的賦值方式給對象book2賦值。改變的值爲,再輸出對象book1的值。
<?php classmyobject{ private $object_type="book"; public function settype($type){ $this->object_type=$type; } public function gettype(){ return $this->object_type; } } $book1=new myobject(); $book2=$book1; $book2->settype("computer"); echo "對象\$book1的值爲:".$book1->gettype(); ?>
上面的實例,在PHP5中的返回值爲:對象的值爲:。因爲book2只是的一個引用,而在中的返回值是:對象book1的值爲:book,由於對象是book1的一個備份。
在PHP5中若是須要將對象複製,也就是克隆一個對象。須要使用關鍵字clone來實現。克隆一個對象的格式爲:
$object1=new classname(); $object2=clone $object1;
(2)、__clone()方法
有時除了單純地克隆對象外,還須要克隆出來的對象能夠擁有本身的屬性和行爲。這時就可使用_clone()方法來實現。__clone()方法的做用是:在克隆對象的過程當中,調用_clone()方法,可使用克隆出來的對象保持本身的一些行爲及屬性。
例:
<?php class myobject{ private $object_type="book"; public function settype($type){ $this->object_type=$type; } public function gettype(){ return $this->object_type; } public function __clone(){ $this->object_type="computer"; } } $book1=new myobject(); $book2=clone $book1; echo "對象$book1的變量值爲:".$book1->gettype(); echo"<br />"; echo "對象$book2的變量值爲:".$book2->gettype(); ?>
<?php classmyobject{ private $name; function __construct($name){ $this->name=$name; } } $book=new myobject(book); $clonebook=clone $book; $referbook=$book; if($clonebook==$book){ echo "兩個對象的內容相等。<br />"; } if($referbook===$book){ echo "兩個對象的引用地址相等。<br />"; } ?>
<?php classmyobject{} class mybook extends myobject{ private $type; } $cbook=new mybook(); if($cbook instanceof mybook){ echo "對象\$cbook屬於mybook類<br />"; } if($cbook instanceof myobject){ echo "對象\$book屬於myobject類<br />"; } ?>
<?php class myobject{ private $type=""; private function __get($name){ if(isset($this->$name)){ echo "變量".$name."的值爲:".$this->$name."<br />"; } else{ echo "變量".$name."未定義,初始化爲0<br />"; $this->$name=0; } } private function __set($name,$value){ if(isset($this->$name)){ $this->$name=$value; echo "變量".$name."賦值爲:".$value."<br />"; }else{ $this->$name=$value; echo "變量".$name."被初始化爲:".$value."<br />"; } } } $mycomputer=new myobject(); $mycomputer->type="DIY"; $mycomputer->type; $mycomputer->name; ?>
(2)、__call()方法
__call()方法的做用是:當程序試圖調用不存在或不可見的成員方法時,PHP會先調用__call()方法來存儲方法名及其參數。__call()方法包含兩個參數,即方法名和方法參數。其中,方法參數是以數組形式存在的。
例:
<?php class myobject{ public function mydream(){ echo "調用的方法存在,直接執行此方法:<br />"; } public function __call($method,$parameter){ echo "若是方法不存在,則執行__call()方法。<br/>"; echo "方法名爲:".$method."<br />"; echo "參數有:"; var_dump($parameter); } } $exam=new myobject(); $exam->mydream(); $exam->mdreadm('how','what','why'); ?>
(3)、sleep()和__wakeup()方法
使用serialize()函數能夠實現序列化對象。就是將對象中的變量所有保存下來,對象中的類則只保存類名。在使用serialize()函數時,若是實例化的對象包含__sleep()方法,則會執行__sleep()方法。該方法能夠清除對象並返回一個該對象中全部變量的數組。使用__sleep()方法的目的是關閉對象可能具備的數據庫鏈接等相似的善後工做。
Unserialize()函數能夠從新還原一個被serialize()函數序列化的對象,__wakeup()方法則是恢復在序列化中可能丟失的數據庫鏈接及相關工做。
例:
<?php class myobject{ private $type="DIY"; public function gettype(){ return $this->type; } public function __sleep(){ echo "使用serialize()函數將對象保存起來,能夠存放到文本文件、數據庫等地方。<br />"; return $this; } public function __wakeup(){ echo "當須要該數據時,使用unserialize()函數對已序列化的字符串進行操做,將其轉換回來對象。<br />"; } } $mybook=new myobject(); $i=serialize($mybook); echo "序列化後的字符串:".$i."<br />"; $rebook=unserialize($i); echo "還原後的成員變量:".$rebook->gettype(); ?>
(4)、tostring()方法
魔術方法這個做用是:當使用echo 或print輸出對象時,將對象轉化爲字符串。
例:
<?php class myobject{ private $type="DIY"; public function __tostring(){ return $this->type; } } $mycomputer=new myobject(); echo "對象\$mycomputer的值爲:"; echo $mycomputer; ?>
(5)、autoload()方法
將一個獨立、完整的類保存到一個PHP頁中,而且文件名和類名保持一致,這是每一個開發人員者須要養成的良好習慣。這樣,在下次重複使用某個類時即能很輕易地找到它。但還有一個問題是讓開發人員頭疼不已的,若是要在一個頁面中引進不少的類,須要使用include_once()函數或require_once()函數一個一個地引入。
PHP5解決了這個問題,__autoload()方法能夠自動實例化須要使用的類。當程序要用到一個類,但該類尚未被實例化時,PHP5將使用__autoload()方法,在指定的路徑下自動查找和該類名稱相同的文件。若是找到,程序則繼續執行,不然,報告錯誤。
例:
Myobject.class.php頁面代碼以下:
<?php classmyobject{ private $cont; public function __construct($cont){ $this->cont=$cont; } public function __tostring(){ return $this->cont; } } ?>
Index.php頁面代碼以下:
<?php function__autoload($class_name){ $class_path=$class_name.'.class.php'; if(file_exists($class_path)){ include_once($class_path); }else{ echo "類路徑錯誤。"; } } $mybook=new myobject("江山代有人才出 各領風騷數百年"); echo $mybook; ?>