- 論壇徽章:
- 0
|
6.如何去使用對(duì)象中的成員
上面看到PHP對(duì)象中的成員有兩種一種是成員屬性,一種是成員方法。對(duì)象我們已經(jīng)可以聲明
了,$p1=new Person();怎么去使用對(duì)象的成員呢?要想訪問對(duì)象中的成員就要使用一個(gè)特殊的操作符“->”來完成對(duì)象成員的訪問:
對(duì)象->屬性 $p1->name; $p2->age; $p3->sex;
對(duì)象->方法 $p1->say(); $p2->run();
如下面實(shí)例:
class Person
{
//下面是人的成員屬性
var $name; //人的名子
var $sex; //人的性別
var $age; //人的年齡
//下面是人的成員方法
function say() //這個(gè)人可以說話的方法
{
echo "這個(gè)人在說話";
}
function run() //這個(gè)人可以走路的方法
{
echo "這個(gè)人在走路";
}
}
$p1=new Person(); //創(chuàng)建實(shí)例對(duì)象$p1
$p2=new Person(); //創(chuàng)建實(shí)例對(duì)象$p2
$p3=new Person(); //創(chuàng)建實(shí)例對(duì)象$p3
//下面三行是給$p1對(duì)象屬性賦值
$p1->name=”張三”;
$p1->sex=”男”;
$p1->age=20;
//下面三行是訪問$p1對(duì)象的屬性
echo “p1對(duì)象的名子是:”.$p1->name.”
”;
echo “p1對(duì)象的性別是:”.$p1->sex.”
”;
echo “p1對(duì)象的年齡是:”.$p1->age.”
”;
//下面兩行訪問$p1對(duì)象中的方法
$p1->say();
$p1->run();
//下面三行是給$p2對(duì)象屬性賦值
$p2->name=”李四”;
$p2->sex=”女”;
$p2->age=30;
//下面三行是訪問$p2對(duì)象的屬性
echo “p2對(duì)象的名子是:”.$p2->name.”
”;
echo “p2對(duì)象的性別是:”.$p2->sex.”
”;
echo “p2對(duì)象的年齡是:”.$p2->age.”
”;
//下面兩行訪問$p2對(duì)象中的方法
$p2->say();
$p2->run();
//下面三行是給$p3對(duì)象屬性賦值
$p3->name=”王五”;
$p3->sex=”男”;
$p3->age=40;
//下面三行是訪問$p3對(duì)象的屬性
echo “p3對(duì)象的名子是:”.$p3->name.”
”;
echo “p3對(duì)象的性別是:”.$p3->sex.”
”;
echo “p3對(duì)象的年齡是:”.$p3->age.”
”;
//下面兩行訪問$p3對(duì)象中的方法
$p3->say();
$p3->run();
?>
從上例中可以看出只是對(duì)象里面的成員就要使用對(duì)象->屬性、對(duì)象->方法 形式訪問,再?zèng)]有第二種方法來訪問對(duì)象中的成員了。
7.特殊的引用“$this”的使用
現(xiàn)在我們知道了如何訪問對(duì)象中的成員,是通過“對(duì)象->成員”的方式訪問的,這是在對(duì)象的外部去訪問對(duì)象中成員的形式,那么如果我想在對(duì)象的內(nèi)部,讓對(duì)象里的方法訪問本對(duì)象的屬性,或是對(duì)象中的方法去調(diào)用本對(duì)象的其它方法這時(shí)我們?cè)趺崔k?因?yàn)閷?duì)象里面的所有的成員都要用對(duì)象來調(diào)用,包括對(duì)象的內(nèi)部成員之間的調(diào)用,所以在PHP里面給我提供了一個(gè)本對(duì)象的引用$this,每個(gè)對(duì)象里面都有一個(gè)對(duì)象的引用$this來代表這個(gè)對(duì)象,完成對(duì)象內(nèi)部成員的調(diào)用, this的本意就是“這個(gè)”的意思,上面的實(shí)例里面,我們實(shí)例化三個(gè)實(shí)例對(duì)象$P1、 $P2、 $P3,這三個(gè)對(duì)象里面各自存在一個(gè)$this分別代表對(duì)象$p1、$p2、$p3 。
![]()
通過上圖我們可以看到,$this就是對(duì)象內(nèi)部代表這個(gè)對(duì)象的引用,在對(duì)象內(nèi)部和調(diào)用本對(duì)象的成員和對(duì)象外部調(diào)用對(duì)象的成員所使用的方式是一樣的。
$this->屬性 $this->name; $this->age; $this->sex;
$this->方法 $this->say(); $this->run();
修改一下上面的實(shí)例,讓每個(gè)人都說出自己的名字,性別和年齡:
class Person
{
//下面是人的成員屬性
var $name; //人的名子
var $sex; //人的性別
var $age; //人的年齡
//下面是人的成員方法
function say() //這個(gè)人可以說話的方法
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
}
function run() //這個(gè)人可以走路的方法
{
echo "這個(gè)人在走路";
}
}
$p1=new Person(); //創(chuàng)建實(shí)例對(duì)象$p1
$p2=new Person(); //創(chuàng)建實(shí)例對(duì)象$p2
$p3=new Person(); //創(chuàng)建實(shí)例對(duì)象$p3
//下面三行是給$p1對(duì)象屬性賦值
$p1->name="張三";
$p1->sex="男";
$p1->age=20;
//下面訪問$p1對(duì)象中的說話方法
$p1->say();
//下面三行是給$p2對(duì)象屬性賦值
$p2->name="李四";
$p2->sex="女";
$p2->age=30;
//下面訪問$p2對(duì)象中的說話方法
$p2->say();
//下面三行是給$p3對(duì)象屬性賦值
$p3->name="王五";
$p3->sex="男";
$p3->age=40;
//下面訪問$p3對(duì)象中的說話方法
$p3->say();
?>
輸出結(jié)果為:
我的名子叫:張三性別:男我的年齡是:20
我的名子叫:李四性別:女我的年齡是:30
我的名子叫:王五性別:男我的年齡是:40
分析一下這個(gè)方法:
function say() //這個(gè)人可以說話的方法
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
}
在$p1、$p2和$p3這三個(gè)對(duì)象中都有say()這個(gè)方法,$this分別代表這三個(gè)對(duì)象, 調(diào)用相應(yīng)的屬性,打印出屬性的值,這就是在對(duì)象內(nèi)部訪問對(duì)象屬性的方式, 如果相在say()這個(gè)方法里調(diào)用run()這個(gè)方法也是可以的,在say()這個(gè)方法中使用$this->run()的方式來完成調(diào)用。
8.構(gòu)造方法與析構(gòu)方法
大多數(shù)類都有一種稱為構(gòu)造函數(shù)的特殊方法。當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),它將自動(dòng)調(diào)用構(gòu)造函數(shù),也就是使用new這個(gè)關(guān)鍵字來實(shí)例化對(duì)象的時(shí)候自動(dòng)調(diào)用構(gòu)造方法。
構(gòu)造函數(shù)的聲明與其它操作的聲明一樣,只是其名稱必須是__construct( )。這是PHP5中的變化,以前的版本中,構(gòu)造函數(shù)的名稱必須與類名相同,這種在PHP5中仍然可以用,但現(xiàn)在以經(jīng)很少有人用了,這樣做的好處是可以使構(gòu)造函數(shù)獨(dú)立于類名,當(dāng)類名發(fā)生改變時(shí)不需要改相應(yīng)的構(gòu)造函數(shù)名稱了。為了向下兼容,如果一個(gè)類中沒有名為__construct( )的方法,PHP將搜索一個(gè)php4中的寫
法,與類名相同名的構(gòu)造方法。
格式:function __construct ( [參數(shù)] ) { ... ... }
在一個(gè)類中只能聲明一個(gè)構(gòu)造方法,而是只有在每次創(chuàng)建對(duì)象的時(shí)候都會(huì)去調(diào)用一次構(gòu)造方法,不能主動(dòng)的調(diào)用這個(gè)方法,所以通常用它執(zhí)行一些有用的初始化任務(wù)。比如對(duì)成屬性在創(chuàng)建對(duì)象的時(shí)候賦初值。
//創(chuàng)建一個(gè)人類
class Person
{
//下面是人的成員屬性
var $name; //人的名子
var $sex; //人的性別
var $age; //人的年齡
//定義一個(gè)構(gòu)造方法參數(shù)為姓名$name、性別$sex和年齡$age
function __construct($name, $sex, $age)
{
//通過構(gòu)造方法傳進(jìn)來的$name給成員屬性$this->name賦初使值
$this->name=$name;
//通過構(gòu)造方法傳進(jìn)來的$sex給成員屬性$this->sex賦初使值
$this->sex=$sex;
//通過構(gòu)造方法傳進(jìn)來的$age給成員屬性$this->age賦初使值
$this->age=$age;
}
//這個(gè)人的說話方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
}
}
//通過構(gòu)造方法創(chuàng)建3個(gè)對(duì)象$p1、p2、$p3,分別傳入三個(gè)不同的實(shí)參為姓名、性別和年齡
$p1=new Person(“張三”,”男”, 20);
$p2=new Person(“李四”,”女”, 30);
$p3=new Person(“王五”,”男”, 40);
//下面訪問$p1對(duì)象中的說話方法
$p1->say();
//下面訪問$p2對(duì)象中的說話方法
$p2->say();
//下面訪問$p3對(duì)象中的說話方法
$p3->say();
?>
輸出結(jié)果為:
我的名子叫:張三性別:男我的年齡是:20
我的名子叫:李四性別:女我的年齡是:30
我的名子叫:王五性別:男我的年齡是:40
如圖:
![]()
析構(gòu)函數(shù):
與構(gòu)造函數(shù)相對(duì)的就是析構(gòu)函數(shù)。析構(gòu)函數(shù)是PHP5新添加的內(nèi)容,在PHP4中沒有析構(gòu)函數(shù)。析構(gòu)函數(shù)允許在銷毀一個(gè)類之前執(zhí)行的一些操作或完成一些功能,比如說關(guān)閉文件,釋放結(jié)果集等,析構(gòu)函數(shù)會(huì)在到某個(gè)對(duì)象的所有引用都被刪除或者當(dāng)對(duì)象被顯式銷毀時(shí)執(zhí)行,也就是對(duì)象在內(nèi)存中被銷毀前調(diào)用析構(gòu)函數(shù)。與構(gòu)造函數(shù)的名稱類似,一個(gè)類的析構(gòu)函數(shù)名稱必須是__destruct( )。析構(gòu)函數(shù)不能帶有任何參數(shù)。
格式:function __destruct ( ) { ... ... }
//創(chuàng)建一個(gè)人類
class Person
{
//下面是人的成員屬性
var $name; //人的名子
var $sex; //人的性別
var $age; //人的年齡
//定義一個(gè)構(gòu)造方法參數(shù)為姓名$name、性別$sex和年齡$age
function __construct($name, $sex, $age)
{
//通過構(gòu)造方法傳進(jìn)來的$name給成員屬性$this->name賦初使值
$this->name=$name;
//通過構(gòu)造方法傳進(jìn)來的$sex給成員屬性$this->sex賦初使值
$this->sex=$sex;
//通過構(gòu)造方法傳進(jìn)來的$age給成員屬性$this->age賦初使值
$this->age=$age;
}
//這個(gè)人的說話方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
}
//這是一個(gè)析構(gòu)函數(shù),在對(duì)象銷毀前調(diào)用
function __destruct()
{
echo “再見”.$this->name.”
”;
}
//通過構(gòu)造方法創(chuàng)建3個(gè)對(duì)象$p1、p2、$p3,分別傳入三個(gè)不同的實(shí)參為姓名、性別和年齡
$p1=new Person(“張三”,”男”, 20);
$p2=new Person(“李四”,”女”, 30);
$p3=new Person(“王五”,”男”, 40);
//下面訪問$p1對(duì)象中的說話方法
$p1->say();
//下面訪問$p2對(duì)象中的說話方法
$p2->say();
//下面訪問$p3對(duì)象中的說話方法
$p3->say();
?>
輸出結(jié)果為:
我的名子叫:張三性別:男我的年齡是:20
我的名子叫:李四性別:女我的年齡是:30
我的名子叫:王五性別:男我的年齡是:40
再見張三
再見李四
再見王五
9.封裝性
封裝性是面向?qū)ο缶幊讨械娜筇匦灾唬庋b性就是把對(duì)象的屬性和服務(wù)結(jié)合成一個(gè)獨(dú)立的相同單位,并盡可能隱蔽對(duì)象的內(nèi)部細(xì)節(jié),包含兩個(gè)含義:1.把對(duì)象的全部屬性和全部服務(wù)結(jié)合在一起,形成一個(gè)不可分割的獨(dú)立單位(即對(duì)象)。2.信息隱蔽,即盡可能隱蔽對(duì)象的內(nèi)部細(xì)節(jié),對(duì)外形成一個(gè)邊界〔或者說形成一道屏障〕,只保留有限的對(duì)外接口使之與外部發(fā)生聯(lián)系。
封裝的原則在軟件上的反映是:要求使對(duì)象以外的部分不能隨意存取對(duì)象的內(nèi)部數(shù)據(jù)(屬性),從而有效的避免了外部錯(cuò)誤對(duì)它的"交叉感染",使軟件錯(cuò)誤能夠局部化,大大減少查錯(cuò)和排錯(cuò)的難度。
用個(gè)實(shí)例來說明吧,假如某個(gè)人的對(duì)象中有年齡和工資等屬性,像這樣個(gè)人隱私的屬性是不想讓其它人隨意就能獲得到的,如果你不使用封裝,那么別人想知道就能得到,但是如果你封裝上之
后別人就沒有辦法獲得封裝的屬性,除非你自己把它說出去,否則別人沒有辦法得到。
再比如說,個(gè)人電腦都有一個(gè)密碼,不想讓其它人隨意的登陸,在你的電腦里面拷貝和粘貼。還有就是像人這個(gè)對(duì)象,身高和年齡的屬性,只能是自己來增漲,不可以讓別人隨意的賦值等等。
使用private這個(gè)關(guān)鍵字來對(duì)屬性和方法進(jìn)行封裝:
原來的成員:
var $name; //聲明人的姓名
var $sex; //聲明人的性別
var $age; //聲明人的年齡
function run(){…….}
改成封裝的形式:
private $name; //把人的姓名使用private關(guān)鍵字進(jìn)行封裝
private $sex; //把人的性別使用private關(guān)鍵字進(jìn)行封裝
private $age; //把人的年齡使用private關(guān)鍵字進(jìn)行封裝
private function run(){……} //把人的走路方法使用private關(guān)鍵字進(jìn)行封裝
注意:只要是成員屬性前面有其它的關(guān)鍵字就要去掉原有的關(guān)鍵字“var”。
通過private就可以把人的成員(成員屬性和成員方法)封裝上了。封裝上的成員就不能被類外面直接訪問了,只有對(duì)象內(nèi)部自己可以訪問;下面的代碼會(huì)產(chǎn)生錯(cuò)誤:
class Person
{
//下面是人的成員屬性
private $name; //人的名子,被private封裝上了
private $sex; //人的性別, 被private封裝上了
private $age; //人的年齡, 被private封裝上了
//這個(gè)人可以說話的方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
}
//這個(gè)人可以走路的方法, 被private封裝上了
private function run()
{
echo "這個(gè)人在走路";
}
}
//實(shí)例化一個(gè)人的實(shí)例對(duì)象
$p1=new Person();
//試圖去給私有的屬性賦值, 結(jié)果會(huì)發(fā)生錯(cuò)誤
$p1->name="張三";
$p1->sex="男";
$p1->age=20;
//試圖去打印私有的屬性, 結(jié)果會(huì)發(fā)生錯(cuò)誤
echo $p1->name.”
”;
echo $p1->sex.”
”;
echo $p1->age.”
”
//試圖去打印私有的成員方法, 結(jié)果會(huì)發(fā)生錯(cuò)誤
$p1->run();
輸出結(jié)果為:
Fatal error: Cannot access private property Person::$name
Fatal error: Cannot access private property Person::$sex
Fatal error: Cannot access private property Person::$age
Fatal error: Cannot access private property Person::$name
Fatal error: Call to private method Person::run() from context ''
從上面的實(shí)例可以看到,私有的成員是不能被外部訪問的,因?yàn)樗接谐蓡T只能在本對(duì)象內(nèi)部自己訪問,比如,$p1這個(gè)對(duì)象自己想把他的私有屬性說出去,在say()這個(gè)方法里面訪問了私有屬性,這樣是可以。(沒有加任何訪問控制,默認(rèn)的是public的,任何地方都可以訪問)
//這個(gè)人可以說話的方法, 說出自己的私有屬性,在這里也可以訪問私有方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
//在這里也可以訪問私有方法
//$this->run();
}
因?yàn)槌蓡T方法say()是公有的,所以我們?cè)陬惖耐獠空{(diào)用say()方法是可以的,改變上面的代碼;
class Person
{
//下面是人的成員屬性
private $name; //人的名子,被private封裝上了
private $sex; //人的性別, 被private封裝上了
private $age; //人的年齡, 被private封裝上了
//定義一個(gè)構(gòu)造方法參數(shù)為私有的屬性姓名$name、性別$sex和年齡$age進(jìn)行賦值
function __construct($name, $sex, $age)
{
//通過構(gòu)造方法傳進(jìn)來的$name給私有成員屬性$this->name賦初使值
$this->name=$name;
//通過構(gòu)造方法傳進(jìn)來的$sex給私有成員屬性$this->sex賦初使值
$this->sex=$sex;
//通過構(gòu)造方法傳進(jìn)來的$age給私有成員屬性$this->age賦初使值
$this->age=$age;
}
//這個(gè)人可以說話的方法, 說出自己的私有屬性,在這里也可以訪問私有方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."
";
}
}
//通過構(gòu)造方法創(chuàng)建3個(gè)對(duì)象$p1、p2、$p3,分別傳入三個(gè)不同的實(shí)參為姓名、性別和年齡
$p1=new Person(“張三”,”男”, 20);
$p2=new Person(“李四”,”女”, 30);
$p3=new Person(“王五”,”男”, 40);
//下面訪問$p1對(duì)象中的說話方法
$p1->say();
//下面訪問$p2對(duì)象中的說話方法
$p2->say();
//下面訪問$p3對(duì)象中的說話方法
$p3->say();
輸出結(jié)果為:
我的名子叫:張三性別:男我的年齡是:20
我的名子叫:李四性別:女我的年齡是:30
我的名子叫:王五性別:男我的年齡是:40
因?yàn)闃?gòu)造方法是默認(rèn)的公有方法(構(gòu)造方法不要設(shè)置成私有的),所以在類的外面可以訪問到,這樣就可以使用構(gòu)造方法創(chuàng)建對(duì)象,另外構(gòu)造方法也是類里面的函數(shù),所以可以用構(gòu)造方法給私有的屬性賦初值。Say()的方法是默認(rèn)公有的,所以在外面也可以訪問的到,說出他自己的私有屬性。
從上面的例子中我們可以看到,私有的成員只能在類的內(nèi)部使用,不能被類外部直接來存取,但是在類的內(nèi)部是有權(quán)限訪問的,所以有時(shí)候我們需要在類的外面給私有屬性賦值和讀取出來,也就是給類的外部提供一些可以存取的接口,上例中構(gòu)造方法就是一種賦值的形式,但是構(gòu)造方法只是在創(chuàng)建對(duì)象的時(shí)候賦值,如果我們已經(jīng)有一個(gè)存在的對(duì)象了,想對(duì)這個(gè)存在的對(duì)象賦值,這個(gè)時(shí)候,如果你還使用構(gòu)造方法傳值的形式傳值,那么就創(chuàng)建了一個(gè)新的對(duì)象,并不是這個(gè)已存在的對(duì)象了。所以我們要對(duì)私有的屬性做一些可以被外部存取的接口,目的就是可以在對(duì)象存在的情況下,改變和存取屬性的值,但要注意,只有需要讓外部改變的屬性才這樣做,不想讓外面訪問的屬性是不做這樣的接口的,這樣就能達(dá)到封裝的目的,所有的功能都是對(duì)象自己來完成,給外面提供盡量少的操作。
如果給類外部提供接口,可以為私有屬性在類外部提供設(shè)置方法和獲取方法,來操作私有屬性.例如:
prvate $age; //私有的屬性年齡
function setAge($age) //為外部提供一個(gè)公有設(shè)置年齡的方法
{
if($age0 || $age>130) //在給屬性賦值的時(shí)候,為了避免非法值設(shè)置給屬性
return;
$this->age=$age;
}
function getAge() //為外部提供一個(gè)公有獲取年齡的方法
{
return($this->age);
}
上面的方法是為一個(gè)成員屬性設(shè)置和獲取值,當(dāng)然你也可以為每個(gè)屬性用同樣的方法對(duì)其進(jìn)行賦值和取值的操作,完成在類外部的存取工作。
本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/30002/showart_363608.html |
|