6.特殊的引用”$this“的使用
我們知道了如何訪問對象中的成員先较,是通過”對象->成員”的方式訪問的,這是在對象的外部去訪問對象中成員的形式, 那么如果我想在對象的內(nèi)部,讓對象里的方法訪問本對象的屬性, 或是對象中的方法去調(diào)用本對象的其它方法這時我們怎么辦?因為對象里面的所有的成員都要用對象來調(diào)用变丧,包括對象的內(nèi)部成員之間的調(diào)用,所以在PHP里面給 我提供了一個本對象的引用$this绢掰。
修改一下上面的實例痒蓬,讓每個人都說出自己的名字,性別和年齡:
class Person {
// 下面是人的成員屬性
var $name; // 人的名子
var $sex; // 人的性別
var $age; // 人的年齡
// 下面是人的成員方法
function say() { // 這個人可以說話的方法
echo "我的名子叫:" . $this->name . " 性別:" . $this->sex . " 我的年齡是:" . $this->age;
}
function run() { // 這個人可以走路的方法
echo "這個人在走路";
}
}
$p1 = new Person(); // 創(chuàng)建實例對象$p1
$p2 = new Person(); // 創(chuàng)建實例對象$p2
$p3 = new Person(); // 創(chuàng)建實例對象$p3
// 下面三行是給$p1對象屬性賦值
$p1->name = "張三";
$p1->sex = "男";
$p1->age = 20;
// 下面訪問$p1對象中的說話方法
$p1->say();
// 下面三行是給$p2對象屬性賦值
$p2->name = "李四";
$p2->sex = "女";
$p2->age = 30;
// 下面訪問$p2對象中的說話方法
$p2->say();
// 下面三行是給$p3對象屬性賦值
$p3->name = "王五";
$p3->sex = "男";
$p3->age = 40;
// 下面訪問$p3對象中的說話方法
$p3->say();
在$p1滴劲、$p2和$p3這三個對象中都有say()這個方法攻晒,$this分別代表這三個對象, 調(diào)用相應(yīng)的屬性班挖,打印出屬性的值鲁捏,這就是在對象內(nèi)部訪問對象屬性的方式, 如果相在say()這個方里調(diào)用run()這個方法也是可以的萧芙,在say()這個方法中使用$this->run()的方式來完成調(diào)用给梅。
7.構(gòu)造方法__construct()與析構(gòu)方法__destruct()
大多數(shù)類都有一種稱為構(gòu)造函數(shù)的特殊方法。當(dāng)創(chuàng)建一個對象時双揪,它將自動調(diào)用構(gòu)造函數(shù)动羽,也就是使用new這個關(guān)鍵字來實例化對象的時候自動調(diào)用構(gòu)造方法。構(gòu)造函數(shù)的聲明與其它操作的聲明一樣渔期,只是其名稱必須是__construct( )运吓。這是PHP5中的變化渴邦,以前的版本中,構(gòu)造函數(shù)的名稱必須與類名相同拘哨,這種在PHP5中仍然可以用谋梭,但現(xiàn)在以經(jīng)很少有人用了,這樣做的好處是可以使構(gòu) 造函數(shù)獨立于類名倦青,當(dāng)類名發(fā)生改變時不需要改相應(yīng)的構(gòu)造函數(shù)名稱了章蚣。為了向下兼容,如果一個類中沒有名為__construct( )的方法姨夹,PHP將搜索一個php4中的寫法,與類名相同名的構(gòu)造方法矾策。
格式:
function __construct ( [參數(shù)] ) { ... ... }
在一個類中只能聲明一個構(gòu)造方法磷账,而是只有在每次創(chuàng)建對象的時候都會去調(diào)用一次構(gòu)造方法,不能主動的調(diào)用這個方法贾虽,所以通常用它執(zhí)行一些有用的初始化任務(wù)逃糟。比如對成屬性在創(chuàng)建對象的時候賦初值。
// 創(chuàng)建一個人類
class Person {
// 下面是人的成員屬性
var $name; // 人的名子
var $sex; // 人的性別
var $age; // 人的年齡
// 定義一個構(gòu)造方法參數(shù)為姓名$name蓬豁、性別$sex和年齡$age
function __construct($name, $sex, $age) {
// 通過構(gòu)造方法傳進來的$name給成員屬性$this->name賦初使值
$this->name = $name;
// 通過構(gòu)造方法傳進來的$sex給成員屬性$this->sex賦初使值
$this->sex = $sex;
// 通過構(gòu)造方法傳進來的$age給成員屬性$this->age賦初使值
$this->age = $age;
}
// 這個人的說話方法
function say() {
echo "我的名子叫:" . $this->name . " 性別:" . $this->sex . " 我的年齡是:" . $this->age;
}
}
// 通過構(gòu)造方法創(chuàng)建3個對象$p1绰咽、p2、$p3,分別傳入三個不同的實參為姓名地粪、性別和年齡
$p1 = new Person("張三","男", 20);
$p2 = new Person("李四","女", 30);
$p3 = new Person("王五","男", 40);
// 下面訪問$p1對象中的說話方法
$p1->say();
// 下面訪問$p2對象中的說話方法
$p2->say();
// 下面訪問$p3對象中的說話方法
$p3->say();
析構(gòu)函數(shù):
與構(gòu)造函數(shù)相對的就是析構(gòu)函數(shù)取募。析構(gòu)函數(shù)是PHP5新添加的內(nèi)容,在PHP4中沒有析構(gòu)函數(shù)蟆技。 析構(gòu)函數(shù)允許在銷毀一個類之前執(zhí)行的一些操作或完成一些功能玩敏,比如說關(guān)閉文件, 釋放結(jié)果集等质礼,析構(gòu)函數(shù)會在到某個對象的所有引用都被刪除或者當(dāng)對象被顯式銷毀時執(zhí)行旺聚,也就是對象在內(nèi)存中被銷毀前調(diào)用析構(gòu)函數(shù)。與構(gòu)造函數(shù)的名稱類似眶蕉, 一個類的析構(gòu)函數(shù)名稱必須是__destruct( )砰粹。析構(gòu)函數(shù)不能帶有任何參數(shù)。
// 創(chuàng)建一個人類
class Person {
// 下面是人的成員屬性
var $name; // 人的名子
var $sex; // 人的性別
var $age; // 人的年齡
// 定義一個構(gòu)造方法參數(shù)為姓名$name造挽、性別$sex和年齡$age
function __construct($name, $sex, $age) {
// 通過構(gòu)造方法傳進來的$name給成員屬性$this->name賦初使值
$this->name = $name;
// 通過構(gòu)造方法傳進來的$sex給成員屬性$this->sex賦初使值
$this->sex = $sex;
// 通過構(gòu)造方法傳進來的$age給成員屬性$this->age賦初使值
$this->age = $age;
}
// 這個人的說話方法
function say() {
echo "我的名子叫:" . $this->name . " 性別:" . $this->sex . " 我的年齡是:" . $this->age;
}
// 這是一個析構(gòu)函數(shù),在對象銷毀前調(diào)用
function __destruct() {
echo "再見" . $this->name;
}
}
// 通過構(gòu)造方法創(chuàng)建3個對象$p1碱璃、p2、$p3,分別傳入三個不同的實參為姓名饭入、性別和年齡
$p1 = new Person("張三", "男", 20);
$p2 = new Person("李四", "女", 30);
$p3 = new Person("王五", "男", 40);
// 下面訪問$p1對象中的說話方法
$p1->say();
// 下面訪問$p2對象中的說話方法
$p2->say();
// 下面訪問$p3對象中的說話方法
$p3->say();
注意:
由于類實例是以堆棧的形式放在內(nèi)存中厘贼,所以最后調(diào)用 析構(gòu)函數(shù) 的時候,輸出順序是按 后進先出 的原則圣拄!
8.封裝性(var與public嘴秸,protected,private的關(guān)系)
public (公有的、默認的)
public 公有修飾符岳掐,類中的成員將沒有訪問限制凭疮,所有的外部成員都可以訪問(讀和寫)這個類成員(包括成員屬性和成員方法),在PHP5之前的所有版本中串述,PHP 中類的成員都是public的执解,而且在PHP5中如果類的成員沒有指定成員訪問修飾符,將被視為public纲酗。
protected (受保護的)
protected保護成員修飾符衰腌,被修飾為protected的成員不能被該類的外部代碼訪問。但是對于該類的子類有訪問權(quán)限觅赊,可以進行屬性右蕊、方法的讀及寫操作,該子類的外部代碼包括其的子類都不具有訪問其屬性和方法的權(quán)限吮螺。
private (私有的)
private 私有修改符饶囚,被定義為private的成員,對于同一個類里的所有成員是可見的鸠补,即沒有訪問限制萝风;但對于該類的外部代碼是不允許改變甚至讀操作,對于該類的子類紫岩,也不能訪問private修飾的成員规惰。
封裝的原則在軟件上的反映是:要求使對象以外的部分不能隨意存取對象的內(nèi)部數(shù)據(jù)(屬性),從而有效的避免了外部錯誤對它的"交叉感染"泉蝌,使軟件錯誤局部化卿拴,大大減少查錯和排錯的難度。
用個實例來說明吧梨与, 假如某個人的對象中有年齡和工資等屬性堕花,像這樣個人隱私的屬性是不想讓其它人隨意就能獲得到的,如果你不使用封裝粥鞋,那么別人想知道就能得到缘挽,但是如果你封裝上之后別人就沒有辦法獲得封裝的屬性, 除非你自己把它說出去呻粹,否則別人沒有辦法得到壕曼。
在比如說,個人電腦都有一個密碼等浊,不想讓其它人隨意的登陸腮郊,在你電腦里面拷貝和粘貼。還有就是像人這個對象筹燕, 身高和年齡的屬性轧飞, 只能是自己來增漲衅鹿,不可以讓別人隨意的賦值等等。
使用private這個關(guān)鍵字來對屬性和方法進行封裝:
private $name; // 把人的姓名使用private關(guān)鍵字進行封裝
private $sex; // 把人的性別使用private關(guān)鍵字進行封裝
private $age; // 把人的年齡使用private關(guān)鍵字進行封裝
private function run(){……} // 把人的走路方法使用private關(guān)鍵字進行封裝
封裝上的成員就不能被類外面直接訪問了过咬,只有對象內(nèi)部自己可以訪問
class Person {
// 下面是人的成員屬性
private $name; // 人的名子大渤,被private封裝上了
private $sex; // 人的性別, 被private封裝上了
private $age; // 人的年齡, 被private封裝上了
// 這個人可以說話的方法
function say() {
echo "我的名子叫:" . $this->name . " 性別:" . $this->sex . " 我的年齡是:" . $this->age;
}
// 這個人可以走路的方法, 被private封裝上了
private function run() {
echo $this->name ."在走路";
}
}
從上面的例子中我們可以看到, 私有的成員只能在類的內(nèi)部使用掸绞, 不能被類外部直接來存取泵三, 但是在類的內(nèi)部是有權(quán)限訪問的, 所以有時候我們需要在類的外面給私有屬性賦值和讀取出來衔掸,也就是給類的外部提供一些可以存取的接口烫幕,上例中構(gòu)造方法就是一種賦值的形式, 但是構(gòu)造方法只是在創(chuàng)建對象的時候賦值敞映,如果我們已經(jīng)有一個存在的對象了较曼,想對這個存在的對象賦值, 這個時候驱显,如果你還使用構(gòu)造方法傳值的形式傳值, 那么就創(chuàng)建了一個新的對象瞳抓,并不是這個已存在的對象了埃疫。所以我們要對私有的屬性做一些可以被外部存取的接口,目的就是可以在對象存在的情況下孩哑,改變和存取 屬性的值栓霜,但要注意,只有需要讓外部改變的屬性才這樣做横蜒,不想讓外面訪問的屬性是不做這樣的接口的胳蛮,這樣就能達到封裝的目的,所有的功能都是對象自己來完 成丛晌,給外面提供盡量少的操作仅炊。
如果給類外部提供接口,可以為私有屬性在類外部提供設(shè)置方法和獲取方法澎蛛,來操作私有屬性抚垄。例如:
private $age; // 私有的屬性年齡
function setAge($age) { // 為外部提供一個公有設(shè)置年齡的方法
if ($age < 0 || $age > 130) // 在給屬性賦值的時候,為了避免非法值設(shè)置給屬性
return;
$this->age = $age;
}
function getAge() { // 為外部提供一個公有獲取年齡的方法
return($this->age);
}
上面的方法是為一個成員屬性設(shè)置和獲取值谋逻, 當(dāng)然你也可以為每個屬性用同樣的方法對其進行賦值和取值的操作呆馁,完成在類外部的存取工作。