php面向物件方法例項(詳細)
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/hj960511/article/details/51479755
一、php面向物件的簡單列子
以人為列子:
<?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); //下面訪問3個物件的說話方式$p1->say();$p2->say();$p3->say(); $p1->say(); //輸出:我的名字叫:小明性別;男我的年齡是:20 $p2->say(); //輸出:我的名字叫:熊性別;女我的年齡是:30 $p3->say(); //輸出:我的名字叫:向日葵性別;男我的年齡是:25 //輸出:再見向日葵 //輸出:再見熊 //輸出:再見小明 ?>
二、php面向物件的幾個步驟
第一類的定義:
<?php
Class myobject{
//……
}
?>
第二成員方法:
<?php
class myobject{
function getobjectname($name){
echo "商品名稱為:".$name;
}
}
?>
第三類的例項化:
<?php class myobject{ function getobjectname($name){ echo "商品名稱為:".$name; } } $c_book=new myobject(); //例項化物件 echo $c_book->getobjectname("計算機圖書"); //呼叫getbookname()方法 //輸出:商品名稱為:計算機圖書 ?>
第四成員變數:
<?php class myobject{ public $object_name; function setobjectname($name){ $this->object_name=$name; } function getobjectname(){ 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; //宣告變數
function setobjectname($name){ //宣告方法setobjectname()
$this->object_name=$name; //設定成員的變數值
}
function getobjectname(){ //宣告方法getobject()
return$this->object_name;
}
}
$c_book=new myobject(); //例項化物件
$c_book->setobjectname("PHP的類"); //呼叫方法setobjectname
echo myobject::book_type."<br>"; //輸出常量的值 //輸出:計算機圖書
echo $c_book->getobjectname(); //呼叫方法getobjectname //輸出:PHP的類
?>
第六面向物件類的構造方法
<?php
class myobject{
public $object_name; //商品名稱
public $object_price; //商品價格
public $object_num; //商品數量
public $object_agio; //商品折扣
…………
}
?>
宣告一個myobject類的物件,並對這個類的一些成員變數賦初值。程式碼如下:
<?php
class myobject{
public $object_name;
public $object_price;
public $object_num;
public $object_agio;
function getobjectname(){
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(); //輸出:western-style clothes
?>
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(); //輸出:western-styleclothes
echo "<br>";
echo $c_book->getobjectname2(); //輸出:1500
?>
第七析構方法:
概念
析構方法的作用和構造方法正好相反,是物件被銷燬時被呼叫的,作用是釋放記憶體。析構方法的格式為:
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(); //輸出:western-styleclothes
echo "<br>";
echo $c_book->getobjectname2(); //輸出:1500
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(); //輸出:western-styleclothes
echo "<br>";
echo $c_book->getobjectname2(); //輸出:1500
//輸出:物件被銷燬,呼叫解構函式。
?>
第八繼承和多狀態的實現
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;
}
function showme(){ //重寫父類中的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()方法 //輸出:本次新進計算機類圖書1000本
echo $h_elec->showme(); //輸出elec子類的是showme()方法 //輸出:熱賣商品:待機王XX系列 原 價:1200 特 價960
?>
子類繼承了父類的所有成員變數和方法,包括建構函式。這就是繼承的實現。
當子類被建立時,PHP會先在子類中查詢構造方法。如果子類有自己的構造方法,PHP會先呼叫子類中的方法,當子類中沒有時,PHP則會去呼叫父類中的構造方法。
兩個子類重寫了父類的方法showme(),所以兩個物件雖然呼叫的都是showme()方法,但返回的卻是兩段不同的資訊。這就是多型性的實現。
第九this−>和操作符的使用1、this−>和操作符的使用1、this->
在 前面類的例項化中,對如何呼叫成員方法有了基本的瞭解,那就是用物件名加方法名,格式為“物件名->方法名”。但在定義類時(如 myobject),根本無法得知物件的名稱是什麼。這時如果呼叫類中的方法,就要用偽變數this−>。this−>。this的意思就是本身,所 以$this->只可以在類的內部使用。
例:
<?php
class example{ //建立類example
function exam(){ //建立成員方法
if(isset($this)){ //判斷變數$this是否存在
echo "\$this的值為:".get_class($this); //如果存在,輸出$this所屬類的名字
}
else{
echo "$this未定義。";
}
}
}
$class_name=new example(); //例項化物件
$class_name->exam(); //呼叫方法exam() //輸出:$this的值為:example
?>
Get_class函式返回物件所屬類的名字,如果不是物件,則返回false。
2、操作符::
相比偽變數$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();
//輸出:本月圖書類冠軍為:conputer
//輸出:本月圖書類冠軍為:foreign language
?>
說明:關於靜態方法(變數)的宣告及使用可參考以下內容。
第十公共、私有和保護
1、 public公共成員
顧名思義,就是可以公開的、沒有必要隱藏的資料資訊。可以在程式的任何地點(類內、類外)被其他的類和物件呼叫。子類可以繼承和使用父類中所有的公共成員。
所有的變數都被宣告為public,而所有的方法在預設的狀態下也是public。所以對變數
和方法的呼叫顯示得十分混亂。為了解決這個問題,就需要使用第二個關鍵字:private。
2、 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(); //輸出:PHP應用開發!
echo "直接操作私有變數的結果:"; //輸出:直接操作私有變數的結果:
echo book::name; //輸出:Fatal error: Undefined class constant 'name' in C:\wamp\www\test\private.php on line 26
?>
對於成員方法,如果沒有寫關鍵字,那麼預設就是public。從本節開始,以後所有的方法及變數都會帶個關鍵字,這是一種良好的書寫習慣。
3、 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(); //輸出:對於protected修飾的變數,在子類中是可以直接呼叫的。如:$name=computer
echo "但在其他的地方是不可以呼叫的,否則:"; //輸出:但在其他的地方是不可以呼叫的,否則:
$lbook->name="history"; //輸出: Fatal error: Cannot access protected property lbook::$name in C:\wamp\www\test\protected.php on line 21
?>
第十一 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關鍵字來宣告,格式為:
Abstract class abstractname{
}
抽象類和普通類相似,都包含成員變數、成員方法。兩者的區別在於,抽象類至少要包含一個抽象方法。抽象方法沒有方法體,其功能的實現只能在子類中完成。抽象方法也是使用abstract關鍵字修飾的。它的格式為:
Abstract function abstractname();
注意:在抽象方法後面要有分號“;”
抽象類和抽象方法主要應用於複雜的層次關係中,這種層次關係要求每一個子類都包含並重寫某些特定的方法。舉一個例子:中國的美食是多種多樣的,有吉菜、魯菜、川菜、粵菜等。每種菜系使用的都是煎、炒、炸等手法,只是在具體的步驟上,各有各的不同。如果把中國美食當作一個大類cate,下面的各大菜系就是cate的子類,而煎炒烹炸則是每個類中都有的方法。每個方法在子類中的實現都是不同的,在父類中無法規定。為了統一規範,不同子類的方法要有一個相同的方法名:decoct(煎)、stir_fry(炒)、cook(烹)、fry(炸)。
例:
<?php
/* 抽象類myobject */
abstract class myobject{ //抽象方法servie
abstract function service($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方法
//輸出:您購買的商品是《PHP從入門到精通》,該商品的價格是:85元您購買的數量為:3本。如發現缺頁、損壞、請在3日內更換。
//輸出:您購買的商品是:XX筆記本,該商品的價格是:8500元。您購買的數量為:1臺。如發生非人為質量問題,請在3個月內更換。
?>
- 介面的使用
繼承特性簡化了物件、類的建立,增加了程式碼的可重性。但PHP只支援單繼承。如果想實現多重繼承,就要使用介面。PHP可以實現多個介面。
介面類通過interface關鍵字來宣告,並且類中只能包含未實現的方法和一些成員變數,格式如下:
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介面。分別實現各自的成員方法後,例項化兩個物件member和member和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,book1,book1的預設值是book,然後將物件book1使用普通資料型別的賦值方式給物件book1使用普通資料型別的賦值方式給物件book2賦值。改變book2的值為computer,再輸出物件book2的值為computer,再輸出物件book1的值。
<?php
class myobject{
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(); //輸出:物件$book1的值為:computer
?>
上面的例項,在PHP5中的返回值為:物件book1的值為:computer。因為book1的值為:computer。因為book2只是book1的一個引用,而在PHP4中的返回值是:物件book1的一個引用,而在PHP4中的返回值是:物件book1的值為:book,因為物件book2是book2是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();
//輸出:Notice: Undefined variable: book1的變數值為: in C:\wamp\www\test\clone2.php on line 24 物件book
//輸出:Notice: Undefined variable: book2的變數值為: in C:\wamp\www\test\clone2.php on line 26 物件computer
?>
1.物件比較
通過克隆物件,相信讀者已經理解表示式boject2=boject2=object1和object2=cloneobject2=cloneobject1所表示的不同含義。但在實際開發中,應如何判斷兩個物件之間的關係是克隆還是引用?
這是可以使用比較運算子==和===。兩個等號是比較兩個物件的內容,3個等號===是比較物件的引用地址。
例: