php的類和對象(翻譯:midiguy)
最後更新:2017-02-28
來源:互聯網
上載者:User
對象 /**********************************************************
翻譯:midiguy
翻譯錯誤之處還請各位指出
E-Mail:midiguy@263.net
QQ:5149927
***********************************************************/
物件導向程式設計的來源得自於人們看待電話、汽車這些物體的想法。很多程式設計者在討論物件導向程式設計的時候喜歡用“封裝”或者“繼承”這些讓一般人迷惑不解的詞語。我們可以把物件導向這個概念和自然物體聯絡起來去理解它的原理。讓我們拿交通工具來做個比方。
設計圖
為了構建交通工具我們需要一份設計圖。這份設計圖可以定義交通工具的車輪的數量、顏色等等。一種交通工具通過一定的屬性和行為來定義。在PHP中這些屬性和行為就叫做變數和方法(函數)。描述一個對象的一組變數和方法就構成了一個“類”。
擴充的設計圖
因為有各種不同類型的交通工具,比如汽車、單車和>機車。我們需要一種方法,它可以讓我們為各種交通工具增加新功能的同時也可以使用交通工具的一般性的方法,換句話說,因為“履帶”要用在所有類型的交通工具上面,我們不需要再重新編寫這種方法。我們能夠“繼承”來完成這個功能。假如我們建立一個從“交通工具”繼承過來的“汽車”的類,所有在“交通工具”類中的方法將被“汽車”類繼承。
抽象
抽象的目的只關注於一個複雜物件的部分性質,為瞭解決你的問題需要你去構建一個考究的對象。你可以很容易的得到一輛汽車成千上萬的屬性,但是如果你需要設計一個程式去儲存一個汽車經銷商的目錄,那麼你應該只需要一個包含10多個屬性的子集。這樣一輛汽車被抽象成一個適合編程使用的汽車對象.
封裝
封裝可以隱藏一組方法的內容工具機制而只提供給使用者一個定義良好的借口。在物件導向程式編程中,封裝使得對象的資料結構和方法組合在一起。最容易理解“封裝”的方式可以參考電話機。當今消費者可以購買各式各樣的電話機,雖然這些電話機的內部設計方法可能不同,但是所有這些電話機器都能夠通過一個標準的公用介面通訊。這就是封裝的思想.
一個類可以定義新資料類型。PHP本身具有變數類型,比如字串變數和浮點類型變數。但是通過類你可以設計自己的資料類型比如船、使用者參考手冊和資料庫等等。一個類定義這種資料類型的屬性和行為(成員變數和方法)。下面的例子顯示如何定義一個包含屬性和方法的類。
讓我們看一下我們的交通工具的實際的例子
<?php
/*
** 如何定義一個類
*/
class Class_Name
{
[var 變數定義]
[Function 方法定義]
}
?>
----------交通工具類------------
<?php
class vehicle
{
/*
** 屬性
*/
var $property1;
var $property2;
var $property3;
/*
** 方法
*/
function setTires($type)
{
if ($type == \"Firestone\")
{
$this->property1 = \"Must be a Ford SUV\";
}
}
function color($col)
{
$this->property2 = $col;
}
}
?>
如何使用定義好的類
類定義好以後,我們就可以建立它的執行個體。為了使用剛才的例子,我們在下面建立一個“交通工具”類的執行個體。
<?php
$myCar = new vehicle();
$myCar->setTires(\"Firestone\");
?>
使用類中的變數
最大的不同點在於使用一個對象和對象擁有的值的種類。一個字串變數倒是很容易理解,因為它擁有一個值。
$myStr = \"PHP stands for... uh.. i forget\";
然而一個對象可以擁有任何種類的值
$myCar->year = 1988;
$myCar->value = 813.77;
$myCar->hasAirbag = false;
$myCar->color = \"periwinkle\";
在PHP中,一個對象的所有成員變數預設是公有的。沒有辦法可以強迫一個對象的訪問屬性,但是如果希望一個變數是私人變數的話,我們可以用一種強調的方式來實現。
$this pointer
如果你想調用一個對象的方法,你可以使用 \'$this\'來調用此對象指定執行個體的成員變數。剛開始,你可能對這個有點不理解,讓我們來看個例子。首先,假設你有兩輛汽車。
$myCar = new vehicle();
$spousesCar = new vehicle();
現在你有了同一個類的兩個對象。你可能也聽過這樣的說法,“現在你有了同一個使用者定義變數類型的兩個綜合變數”。 These are just different ways of talking about the same OOP concepts.
每個變數,$myCar 和 $spousesCar, 擁有這個類的獨立的一套屬性。
$myCar->property1;
//這兩個是不同的
$spousesCar->property1;
//即使property1隻在類定義中出現一次。你必須清楚,它僅僅是為了構成一個新資料類型而設計的。
但是在這個類內只有一個setTires()函數。當我們使用下面的語句的時候,它如何瞭解是誰調用了它呢?
$myCar->setTires(\"Firestone\");
呵呵,現在這個$this就起作用了。在一個指定對象調用類內部的函數時候,這個對象就自動作為一個參數傳遞。用$this是出於方便的需要。看看下面的例子你應該可以理解。
$myCar->setTires(\"Firestone\");
/*
** 方法
*/
function setTires($type)
{
if ($type == \"Firestone\")
{
$this->property1 = \"Must be a Ford SUV\";
}
}
//$this 代表 $myCar 變數
$spousesCar->setTires(\"Goodyear\");
/*
** 方法
*/
function setTires($type)
{
if ($type == \"Firestone\")
{
$this->property1 = \"Must be a Ford SUV\";
}
}
//現在它就代表 $spousesCar.
建立一個構造器
在一個類的執行個體被建立以後,如果開發人員希望能有一個“預設”的函數可以調用,該怎麼辦呢?這就是要用到“構造器”
其實你只需要簡單的將構造器的名字定義為類的名字就可以實現。現在你每次建立這個類的對象的時候,這個構造器方法將被調用。
類的繼承
我們以前說過,一個類可以繼承另一個類;但是我們如何利用這種功能呢?在一個系統中,許多變數起相同的作用,僅僅一些的作用有些不同,繼承是非常有用的。繼承是一種方法,通過這種方法,一個類可以用另外一個類作為模板來建立自身。繼承類將把在被繼承類中定義的成員變數和方法繼承過來。通過延伸或者繼承過來的類叫做子類。被繼承類的叫做超類或父類。這樣可以使類之間的作用不同並且不會影響現存的代碼.現在讓我們看個例子。
class Airplane {
var $tirePressure;
var $fuelLevel;
var $passengerLimit;
function takeOff() {
...
}
function land() {
...
}
function preFlightCheck() {}
}
class sevenFortySeven extends Airplane {
function preFlightCheck() {
//747飛機起飛預備工作
}
}
class biplane extends Airplane {
function preFlightCheck() {
//雙翼飛機起飛預備工作
}
}
$planeArray[] = new biplane();
$planeArray[] = new sevenFortySeven();
$planeArray[] = new sevenFortySeven();
$planeArray[] = new biplane();
for ($x = 0; $x < count($planeArray); $x++) {
$currentPlane = $planeArray[$x];
if ($currentPlane->preFlightCheck() ) {
$currentPlane->takeOff();
//不管是什麼型號的飛機,它都會知道它要起飛了
} else {
print \"飛機出了點問題.\";
}
}
類的靜態方法
當處理一個類的對象的時候,你可能放一個對這個對象有用的函數在這個類中,而不是再另寫一個特殊類。這樣的函數叫做靜態方法。一個良好
類應該包含所有有用的(utility)函數。
class Money {
function addTax($amount,$percent){
return $amount + ($amount * $percent);
}
function convertCurrency ($amount, $from, $to) {
//在資料庫中尋找一個從$from變換到$to的轉換率
return $amount * $rate;
}
}
$total = Money::addTax($subtotal,6.5);
$yen = Money::convertCurrency ($usd, \"america\", \"japan\");
方法工廠(Factory Methods)
有時候將代碼分成一個一個的塊去建立對象很有好處。你可以使用大量的類,也可以使用一個類來決定對象使用工廠類(factory methods)。
工廠類可以協助你有效組織你的代碼。一般情況下,工廠類包含一個比較大的轉換聲明並且返回一個合適的對象的執行個體。讓我們看個有關C掃描
儀的例子。有一個Item基本類, 但是也有很多子類,這些子類可以為各種各樣的產品調用(比如電子類的, 服裝類的...)。
Class Item {
var $price;
var $isTaxable;
var $properties;
function getNewItem($upc) {
//串連到資料庫
//尋找$upc的類型並將其放入$type變數中
//尋找$upc的屬性並將其放如$attrib變數中;
return new $type($attrib);
}
}
class produce extends Item {
function produce ($a) {
$this->properties = $a;
}
function requiresScale() {
return true;
}
}
class hardlines extends Item {
function hardlines ($a) {
$this->properties = $a;
}
function requiresSclae() {
return false;
}
}
while ( $upc = $scanner->next_code() ) { //假設有一個掃描器的類
$z = Item::getNewItem($upc);
if ($z->requiresScale() ) {
echo \"需要尺寸!\";
}
$subtotal += $z->properties[\"price\"];
}