淺談PHP面向物件程式設計(二)
和一些面向物件的語言有所不同,PHP並不是一種純面向物件的語言,包PIP它支援面向物件的程式設計,並可以用於開發大型的商業程式。因此學好面向物件輸程對PHP程式設計師來說也是至關重要的。本章並針對面向物件程式設計在PIP語言中的使用進行詳細講解。
2.1 面向物件概述
面向物件是一種符合人類思維習慣的程式設計思想。現實生活中存在各種形態不同的事物,這些事物之間存在著各種各樣的聯絡。在程式中使用物件來對映現實中的事物,使用物件的關係來描述事物之間的聯絡,這種思想就是面向物件。
提到面向物件,自然會想到面向過程,面向過程就是分析解決問題所需要的步驟,然後用函式把這些步驟一一實現。使用的時候一一個個依次呼叫就可以了。面向物件則是把解決的問題按照一定規則劃分為多個獨立的物件,然後通過呼叫物件的方法來解決問題。當然,一個應用程式會包含多個物件,通過多個物件的相互配合來實現應用程式的功能。這樣當應用程式功能發生變動時,只需要修改個別的物件就可以了,從而使程式碼更容易維護。面向物件的特點主要可以概括為封裝性、繼承性和多型性。接下來針對這三種特性進行簡單介紹。
1. 封裝性
封裝是面向物件的核心思想,將物件的屬性和行為封裝起來,不需要讓外界知道具體實現細節,這就是封裝思想。例如,使用者使用計算機,只需要使用手指蔽鍵盤就可以了,無領知道計算機內部是如何工作的,即使使用者可能碳巧知道計算機的工作原理。但在使用時。也不會完全依賴計算機工作原理這些細節。
2.繼承性
繼承性主要描述的是類與類之間的關係,通過繼承,可以在無須重新編寫原有類的情況下,對原有類的功能進行擴充套件。例如,有一個汽車的類,該類中描述了汽車的普通特性和功能,面轎車的類中不僅應該包含汽車的特性和功能,還應該增加轎車特有的功能,這時。可
以讓轎車類繼承汽車類、在轎車類中單獨漆加轎車特性的方法就可以了,繼承不僅增強了程式碼的複用性 提高了程式開發效率而且為程式的修改補充提供了便利。
3.多型性
多型性指的是同一操作作用於不同的物件,會產生不同的執行結果。例如當聽到Cout這個單詞時,理髮師的表現是剪髮演員的行為表現是表演, 不同的物件,所表現的行為是不一樣的
面向物件的程式設計思想博大精深,初學者僅僅靠文字介紹是不能完全理解的,必須通過大量的實踐和思考,才能真正領悟。希望大家帶著面向物件的思想來學習後續的課程,來不斷加深對面向物件的理解
2.2 類與物件
面向物件的編星思想力圖使程式對事物的描述與該事物在現實中的形態保持一致。為了做到這一點,在面向物件的思想中提出了兩個概 即類和物件。其中,類是對某類事物的拍象描述,而物件用於表示現實中該類事物的個體。
class 類名{ 成員屬性; 成員方法; }
上述語法格式中,class 表示定義類的關鍵字,通過該關鍵字就可以定又一個類。在類中直明的變數被稱為成員屬性,主要用於描述物件的特徵,如人的姓名、年齡等。在類中宣告的函式被稱為成員方法,主要用於描述物件的行為,如人可以說話、走路等。
接下來通過一個案例來演示如何定義個類, 如例2-1所示。 例2-1
<?php //定義一個Person類 class Person { public $name; public $age; public function speak(){ echo "大家好!我叫".$this->name.",今年".$this->age."歲。<br>"; } } ?>
例2-1中定義了一個類。其中,Person是類名,name和age是成員屬性,speak()是成員方法。在成員方法spcak()中可以使用$this訪向成員屬性name和age.需要注意的是。 $this表示當前物件,這裡是指Person類例項化後的具體物件。
2.2.2物件的建立
應用程式想要完成具體的功能,僅有類是遠遠不夠的,還需要根據類建立例項物件。在PHP程式中可以使用NEW關鍵字來建立物件,具體格式如下:
$物件名=new類名([ 引數1,.引數2]);
上述語法格式中。“$物件名”表示一個物件的引用名稱,通過這個引用就可以訪問物件中的成員,其中$符號是固定寫法,物件名是自定義的。new表示要建立一個新的物件。類名”表示新物件的型別。“[引數1.引數2]"中的引數是可選的。物件建立成功後。就可以通過“物件一>成員”的方式來訪問類中的成員。名要注意的是,如果在建立物件時,不需要傳遞引數。則可以省路類名後面的括號,即“new類名:”。
接下來通過一個案例來演示如何建立Person類的例項物件。如例2-2所示
例2-2
<?php //定義一個Person類 class Person { public $name; public $age; public function speak(){ echo "大家好!我叫".$this->name.",今年".$this->age."歲。<br>"; } } $p1=new Person(); $p1->name = "張華"; $p1->age = 10; $p1->speak(); ?>
執行結果
在例2-2中,定義了一個Person物件$pl.然後通過該物件為name和age屬性賦值,井呼叫speak()方法。從執行結果可以看出,程式輸出了$p1物件的姓名和年齡。
2.2.3類的封裝
在例2-2中定義的Person類有兩個屬性 name和age.在為age賦值時。由於沒有做限定,因此可以賦於任何值,甚至一個負數。然面,將年齡賦值為一個負數顯然是不符合實際生活的為了防止這種情況出現,在設計一個類時,應該對成員交量的訪問做出一些限定.不允許外界隨意訪問,此時就需要實現類的封裝。
所謂類的封裝是指在定又一個類時將類中的屬性私有化,即使用pnvate關鍵字來修飾。私有化的屬性只能在它所在類中技訪問,為了能讓外界訪問私有屬性。PHP提供了兩種形式,接下來將針對這兩種形式進行詳細講解
通過getxx()和setXxx()方法訪問私有屬性
在PHP程式中,為了可以訪問私有屬性。可以手動編寫公有的geXxx()和setXxx()方法,其中,geXxx()方法用於獲取屬性值,setXxx()方法用於設定屬性值。 接下來通過一個案例來演示這兩個方法的使用,如例2-3所示
例2-3
<?php class Person { private $name; private $age; //定義getName()和setName()方法用於獲取和設定$name屬性 public function getName() { return $this->name; } public function setName($value) { $this->name=$value; } //定義getAge()和setAge()方法用於獲取和設定$age屬性 public function getAge() { return $this->age; } public function setAge($value) { if($value<0){ echo "年齡不合法<br>"; }else{ $this->age=$value; } } } $p1=new Person(); $p1->setName("張華"); $p1->setAge(-10); echo "姓名:".$p1->getName()."<br>"; echo "年齡:".$p1->getAge(); ?>
執行結果
在例2-3的Person類中,使用prvate關鍵字將屬性name和sge宣告為私有,並對外界提供了公有的方法.其中getName()方法用於獲取name屬性的值.setName()方法用於設定name屬性的值,同理,getAge()和 setAge()方法用於獲取和設定age屬性的值。在建立Person物件時。呼叫setAge()方法傳入一個負數-10,在selAge()方法中對引數$value的值進行檢查、由於當前傳人的值小於0.因此會列印“年齡不合法”的資訊,ase屬性不會被賦值。
通過_ _get()和_ _ set ()方法訪問私有屬性
上述形式在實現封裝時,獲取屬性使用的都是手動編寫的getXxx()和setXxx()方法,當一個類中有多個屬性時,使用這種方式就會很麻煩。為此,PHP5中預定義了_ get()方法和_ set()方法其中get()方法 用於獲取私有成員屬性的屬性值,set()方法用於為私有成員屬性賦值,這個兩個方法獲取私有屬性和設定私有屬性時都是自動呼叫的 接下來通過一個案例2-4來演示這個方法的使用。
例2-4
<?php class Person { private $name; //將$name屬性封裝 private $age; //將$age屬性封裝 //定義__get()方法用於獲取Person的屬性 public function __get($property_name){ echo "自動呼叫__get()方法獲取屬性值<br>"; if(isset($this->$property_name)){ return($this->$property_name); }else{ return(NULL); } } //定義__set()方法用於設定Person的屬性 public function __set($property_name,$value){ echo "自動呼叫__set()方法為屬性賦值<br>"; $this->$property_name=$value; } } $p1=new Person(); $p1->name = "張華"; $p1->age = 10; echo "姓名:".$p1->name."<br>"; echo "年齡:".$p1->age; ?>
執行結果
在例2-4的Person類中,通過封裝的形式定又了兩個屬性name和age,並提供了_get()和__set()方法,用於對屬性的賦值和訪問,從執行結果可以看出,通過__get()方法 和__ set()方法,實現了對私有屬性的訪同以及賦值功能並且程式會自動呼叫__ get()方法和_ _set()方法 .在PHP中,提供了三個訪問修飾符public. protected 和pnvate.它們可以對類中成員的訪問作出一些限制,具體如下:
public:公有修飾符,類中的成員將沒有訪問限制,所有的外部成員都可以訪問這個類的成員。如果類的成員沒有指定訪問修飾符,則預設為public.
protected: 保護成員修飾符,被修飾為protected 的成員不能被該類的外部程式碼訪問,但是對於該類的子關可以對其訪問、讀寫等。
pnvate: 私有修飾符,被定義為private 的成員,對於同一個關裡的所有成員是可見的,即沒有訪問限制,但不允許該類外部的程式碼訪問,對於該類的子類同樣也不能訪問。
需要注意的是,在PHP4中所有的屬性都用關鍵字var宣告,它的使用效果和使用public一樣。因為考慮到向下相容,PHPS 中保留了對var的支援。但會將var自動轉換為pubic.
2.2.4 特殊的$this
物件一旦被建立,在物件的每個成員方法中都會存在個特殊的物件引用 "Sthis".它代表當前物件,用於完成物件內部成員之間的訪問。其語法格式如F :$this->屬性名;
為了更好地理解$this的用法.接下來通過一個案例來演示如何使用$this訪問物件內部的成員屬性,如 例2-5所示
1 <?php 2 //定義一個Person類 3 class Person { 4 public $name; 5 public $age; 6 public function speak(){ 7 echo "大家好!我叫".$this->name.",今年".$this->age."歲。<br>"; 8 } 9 } 10 $p1=new Person(); 11 $p1->name = "張華"; 12 $p1->age = 10; 13 $p1->speak(); 14 $p2=new Person(); 15 $p2->name = "紫晴"; 16 $p2->age = 13; 17 $p2->speak(); 18 ?>
執行結果
在例2-5中.建立了Person類的兩個例項物件$pI .$p2.然後通過這兩個物件分別為name、age屬性賦值,並呼叫speak()方法。從執行結果可以看出,當$p1 物件呼叫speak()方法時,會輸出$pI物件的屬性值,當$p2 物件呼叫speak()方法時,會輸出$p2物件的屬性值。因此,可以說明$this表示的是當前類的當前物件。
注意: $this 不能在類定義的外部使用,只能在類定義的方法中使用。$this在靜態方法中不能使用 ,靜態方法中也不應呼叫非靜態方法。