




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
107-面向?qū)ο蟮恼軐W面向?qū)ο?/p>
PHP5中非常重要的一個概念
面向?qū)ο蟮恼軐W
面對對象的概念(類是什么?
對象是什么?)
面向?qū)ο蟮幕A(chǔ)語法聲明類
如何創(chuàng)建一個對象
沒有面向?qū)ο笾?我們能否開發(fā)程序?
答:當然可以.
比如
c語言,沒有類與對象的概念.
被稱為面向過程的語言.
面向?qū)ο笈c面向過程,同樣是一種編程范式.
回顧以往的代碼
每一個步驟,每個分支,都是我們考慮進來,并加以控制的.
如果步驟/人物角色/分支
特點多的時候,
程序龐大,不好維護.
而從開發(fā)角度講,無論你多少分支,多少步驟.
這1W或2W個步驟,也是在我們的討論范圍內(nèi)的一個確定情況.
=============
比如一只雞,他有可能來叨菜葉,也有可能不來.
這個事情,就沒必要在你創(chuàng)建之初定義下來.
定義一只雞
這樣的一個對象,
他有一定的智商,有一定的功能,比如叨菜葉.
至于去不去,
受環(huán)境的影響,比如菜葉的大小,園子的遠近
就是說:
作為上帝,創(chuàng)建有功能的"對象".
對象有一定的功能,
對象與對象之間在其功能范圍內(nèi),相互操作.
至于做哪些操作?
比如
公雞可以去吃沙子,可以去吃菜葉,也可以斗架.
<?php
//01.php
/*
從地址欄接收
gender參數(shù),男/女
模擬商場迎賓的行為:
如顧客為男:
則招呼
"先生好";
如顧客為女:
則招呼
"女士好";
用地址欄的參數(shù)來模擬顧客的性別.
*/
$g
=
$_GET['gender'];
if($g
==
'男')
{
echo
'先生好';
}
else
if($g
==
'女')
{
echo
'女士好';
}
else
{
echo
'妖猴!';
}
/*
這個程序,
對于可能性的判斷,都被我們詳細的討論到,
并為每一種可能準備的相應(yīng)的操作.
*/
?>
<?php
//02.php
/*
張三
張三的智商
張三打招呼
車
車撞人
以往我們分析:
收到什么數(shù)據(jù)
做什么判斷
各自再怎么處理
我們把張三看成一個對象
張三有智商>
屬性[名字]
張三能打招呼
>功能/方法[動詞]
車也是一個對象
車能撞人
>
功能/方法[動詞]
*/
class
Man
{
public
$iq
=
100;
public
function
say()
{
$arr
=
array('早上好','晚上好','尼妹呀');
if($this->iq
>=
100)
{
echo
$arr[0];
}
else
{
$i
=
rand(0,2);
echo
$arr[$i];
}
}
}
class
Car
{
public
function
hit($people)
{
$newiq
=
rand(50,110);
$people->iq
=
$newiq;
}
}
$lisi
=
new
Man();
=
new
Car();
$lisi->say();
echo
'<br
/>';
//
撞擊
$QQ->hit($lisi);
echo
$lisi->iq,'<br
/>';
$lisi->say();
echo
'<br
/>';
$lisi->say();
echo
'<br
/>';
$lisi->say();
echo
'<br
/>';
/****
這一道題的目的是讓大家換個思維,換個面向?qū)ο蟮乃季S來看待問題.
至此里面的語法,你不懂,沒關(guān)系.
****/
?>108-類與對象的概念先從生活中的角度來理解面向?qū)ο?/p>
類的概念
對象的概念
以女媧造人為例,
女媧看到人世間冷清,于是在水中照見自己的形象
并在自己的形象基礎(chǔ)上構(gòu)思,加上2條腿.
動手捏泥人!
思考問題1:
在泥人產(chǎn)生之前,先產(chǎn)生的是"女媧在腦子中構(gòu)造的人的形象"
然后根據(jù)形象來捏人.
思考問題2:
捏的人
都有一個什么特點和人的形象相符
換句話說:
人的形象
是抽象的,用來說明人的共同特點的.
而每一個人,是具體的,且符合形象的描述.
類:
就是所有對象共同點的一個抽象.
就是一個制造說明書!
對象:
就是根據(jù)說明書造出來的具體對象.
====我買過一個四層書柜,
原以為是現(xiàn)成書柜,送來貨后發(fā)現(xiàn)是
說明書+板子+螺絲
說明書上說清了
A板
B板如何結(jié)合
并畫了一張圖,就是組裝成功后的圖.
我照著圖--最終組裝一個書柜.
說明書就是類.
書柜就是對象.
???
如果原材料非常多,我造1000個書柜,
需要幾份說明書
答:還是1份.
===========如果我們在PHP中用面向?qū)ο蟮脑?===
想造N個人的對象,
需要先:
創(chuàng)建人類,且只需要創(chuàng)建1次.
然后再:
由類創(chuàng)造人的對象,可以N次.
=======如果聲明類====
對象有什么?
屬性(身高,體重,姓名)
對象能干什么?
功能(哭,笑,招呼,吃飯)
我們用"變量","函數(shù)"來模擬"屬性"/"功能"
我們把
{N個屬性+N個方法}
打包成一個"東西",--就是對象.
其實就是N個變量,
N個函數(shù),
打包到某個對象里.
這個對象可以使用這N個變量,N個函數(shù)
<?php
//03.php
/**
人類
聲明語法:
class
類名
{
}
這個類,沒有屬性,也沒有方法
**/
class
People
{
//
public
的含義先別管
public
$name
=
'nobody';
public
$height
=
30;
public
function
cry()
{
echo
'呱呱墜地';
}
}
/****
有了類,就可以產(chǎn)生對象了.
如何類來產(chǎn)生對象?
new
類名();
這個語句返回對象
返回的對象
賦給一個變量
****/
$a
=
new
People();
print_r($a);
/***
這個a是什么
,a對象
就是一個箱子,里面裝了N多屬性和屬性值
$a
=
{name:nobody,height:30}
可以看出
$a是一個復(fù)合數(shù)據(jù),
我們要想訪問$a的名字,即$a里面
name的值,
我們可以怎么訪問呢?
答:肯定是得通過$a來訪問了.
$a->屬性名,就可訪問該屬性的值
***/
echo
$a->name,'<br
/>',$a->height,'<br
/>';
$b
=
array('name'=>'nobodyB','height'=>'40B');
echo
$b['name'],'<br
/>',$b['height'];
echo
'<br
/>';
//
====
對象調(diào)用其方法====//
$a->cry();
?>109-屬性與方法的注意點<?php
//04.php
//
聲明類的時候,注意點.
/*
1:關(guān)于屬性值,可以聲明屬性并賦值,也可以聲明屬性先不賦值
如果不賦值,則屬性的初始值是NULL
2:
關(guān)于PHP中的類,請注意,屬性必須是一個"直接的值"
是8種類型任意的"值".
不能是:
表達式
1+2
的值
不能是:
函數(shù)的返回值
time();
這點和java不一樣.
*/
class
Human
{
//
public
$age
=
time();
//
錯誤
//
public
$age
=
1+2;
//
錯誤
}
$a
=
new
Human();
echo
$a->age,'<br
/>';
class
People
{
public
$age;
}
$b
=
new
People();
var_dump($b->age);
echo
'<br
/>';
?>
<?php
//05.php
//
方法的注意點
function
t()
{
echo
't';
}
//
這個t是我的自定義函數(shù)
t();
//
我再定義一個t函數(shù)
/*
Fatal
error:
Cannot
redeclare
t()
(previously
declared
in
D:\www\1105\05.php:5)
in
D:\www\1105\05.php
on
line
16
function
t()
{
echo
'tt';
}
PHP中函數(shù)不能重復(fù)定義
這點和js不一樣
*/
/**
time是系統(tǒng)函數(shù),因此你也不能再次定義
function
time()
{
}
**/
/***
但是,類中的方法,可以理解"包在類范圍內(nèi)的函數(shù)"
和全局的函數(shù)不是一回事,
因此,可以重名
***/
class
clock
{
public
function
time()
{
echo
'現(xiàn)在的時間戳是aaaa';
}
public
function
t()
{
return
'內(nèi)部的t';
}
public
function
time2()
{
echo
'現(xiàn)在的真正時間戳是',time(),'<br
/>';
//
注意此處調(diào)用的是系統(tǒng)的time()函數(shù)
echo
$this->t();
//
注意,此處調(diào)用的是自身的t函數(shù);
}
}
$c
=
new
clock();
$c->time();
echo
'<br
/>';
$c->time2();
?>110-構(gòu)造函數(shù)詳解<?php
//01.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
構(gòu)造函數(shù)
__construct()
***/
/****
代碼部分
****/
header('Content-type:text/html;
charset=utf-8');
class
Human
{
public
$name
=
'李四';
public
$gender
=
'男';
}
$a
=
new
Human();
$b
=
new
Human();
$c
=
new
Human();
echo
$a->name,'<br
/>';
echo
$b->name,'<br
/>';
echo
$c->name,'<br
/>';
echo
$a->gender,'<br
/>';
echo
$b->gender,'<br
/>';
echo
$c->gender,'<br
/>';
/*
在上面的例子中,
體現(xiàn)出類是模板,對象根據(jù)模板造出的實例.
但是,模板是固定的.
因此,導致造出來的對象,各種屬性值都一樣.
這顯示與現(xiàn)實生活中的邏輯不符.
比如:
新生兒,
性別
姓名
體重
這些都不一樣.
同一個模板,不同的對象
這就是一對矛盾?
答:___
想一想:
為什么新生兒有的是男,有的是女?
答:因為,染色體不一樣.
x,y
->男
x,x-->女
造對象時,傳x染色體,還是y染色體,都有可能
這就說明創(chuàng)建對象時,可以傳參
在類中,
有一個構(gòu)造函數(shù),
就是用來初始化對象用的.
利用構(gòu)造函數(shù),你有機會操作對象,
并改變他的值
*/
?>
<?php
//02.php
/***
====筆記部分====
構(gòu)造方法
__construct();
注意
前面是兩個下滑線
構(gòu)造方法的作用時機:
每當new一個對象,就會自動新new出來的對象發(fā)揮作用
new
ClassName($args);
$args參數(shù)原樣傳給構(gòu)造方法;
然后構(gòu)造方法,用參數(shù)來影響新創(chuàng)建的對象
當然:new
ClassName()
也可以不傳參
但注意:
$args要與構(gòu)造方法里的參數(shù)一致.
***/
/*
class
Human
{
public
function
__construct()
{
echo
'紫微星下凡了!';
}
public
$name
=
null;
public
$gender
=
null;
}
$a
=
new
Human();
*/
//
構(gòu)造函數(shù)的傳參,并影響對象
/*
class
Human
{
public
function
__construct()
{
$this->name
=
'李四';
$this->gender
=
'女';
}
public
$name
=
null;
public
$gender
=
null;
}
$a
=
new
Human();
$b
=
new
Human();
$c
=
new
Human();
echo
$a->name,'<br
/>';
//
李四
echo
$b->name,'<br
/>';
//
李四
echo
$c->name,'<br
/>';
//
李四
*/
class
Human
{
public
function
__construct($name,$gender)
{
$this->name
=
$name;
$this->gender
=
$gender;
}
public
$name
=
null;
public
$gender
=
null;
}
$a
=
new
Human('張飛','男');
$b
=
new
Human('空姐','女');
$c
=
new
Human('孫二娘','女');
$d
=
new
Human();
echo
$a->name,'<br
/>';
//
張飛
echo
$b->name,'<br
/>';
//
空姐
echo
$c->name,'<br
/>';
//
孫二娘
?>
<?php
//03.php
/***
====筆記部分====
析構(gòu)函數(shù):
__destruct()
構(gòu)造函數(shù)是在對象產(chǎn)生的時候,自動執(zhí)行
析構(gòu)函數(shù)是在對象銷毀的時候,自動執(zhí)行
構(gòu)造函數(shù)就是出生時啼哭
析構(gòu)函數(shù)就是臨終遺言
對象如何銷毀?
1:顯式的銷毀,
unset
,賦值為NULL,都可以
2:PHP是腳本語言,在代碼執(zhí)行到最后一行時,
所有申請的內(nèi)存都要釋放掉.
自然,對象的那段內(nèi)存也要釋放,對象就被銷毀了.
對于PHP所做的WEB程序,想犯內(nèi)存泄露的錯誤也很難.
***/
class
Human
{
public
$name
=
null;
public
$gender
=
null;
public
function
__construct()
{
echo
'出生了<br
/>';
}
public
function
__destruct()
{
echo
'終究沒能逆襲!<br
/>';
}
}
$a
=
new
Human();
$b
=
new
Human();
$c
=
new
Human();
$d
=
new
Human();
unset($a);
$b
=
true;
$c
=
NULL;
//
死3次
echo
'<hr
/>';
/*
63行也執(zhí)行完畢,頁面執(zhí)行完畢,
$d
得回收,
*/
/***
最后一次銷毀,是PHP的頁面執(zhí)行完畢了,63行也執(zhí)行完畢了.
然后系統(tǒng)回收,
$d此時才銷毀,
因此
顯示hr
即灰線后面
***/111-析構(gòu)函數(shù)與回收機制深度講解<?php
//04.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
疑問:
1:把對象賦值為其他,比如true
會不會銷毀對象?
小K
(21:07:15)
試了下,也可以
2:上一頁的案例
為什么銷毀一個
空2個
最后一個會出現(xiàn)在灰線下面?
答:
最后一次銷毀,是PHP的頁面執(zhí)行完畢了,63行也執(zhí)行完畢了.
然后系統(tǒng)回收,
$d此時才銷毀,
因此
顯示hr
即灰線后面
***/
/****
代碼部分
****/
///
對象的回收機制
///
class
Human
{
public
$name
=
'張三';
public
$gender
=
null;
public
function
__destruct()
{
echo
'死了!<br
/>';
}
}
$a
=
new
Human();
$b
=
$c
=
$d
=
$a;
echo
$a->name,'<br
/>';
echo
$b->name,'<br
/>';
$b->name
=
'李四';
echo
$a->name,'<br
/>';
echo
$b->name,'<br
/>';
unset($a);
//
$b,$c,$d在指向?qū)ο?因此對象不能銷毀.
echo
'<hr
/>';
/*
1:死幾次
2:死上灰線上,還是死在灰線下
*/
/*
在此處,頁面運行完畢,對象銷毀,執(zhí)行析構(gòu)函數(shù).
銷毀了幾個對象?
答:
只有一個對象,只死1次
死在系統(tǒng)回收時,即頁面執(zhí)行完畢,因此在灰線下.
*/
?>
<?php
//05.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
***/
/****
代碼部分
****/
class
Human
{
public
$name
=
'張三';
public
$gender
=
null;
public
function
__destruct()
{
echo
'死了!<br
/>';
}
}
$e
=
$f
=
$g
=
new
Human();
unset($e);
echo
'unset
e<br
/>';
unset($f);
echo
'unset
f<br
/>';
unset($g);
echo
'unset
g<br
/>';
/*
unset
e
unset
f
死了
unset
g;
*/
?>
<?php
//06.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/****
代碼部分
****/
class
Human
{
public
$name
=
'lisi';
public
function
who()
{
echo
$this->name;
}
public
function
test()
{
echo
$name;
}
}
$a
=
new
Human();
echo
$a->name,'<br
/>';
//
lisi
$a->who();
/*
和java,c++相比
方法體內(nèi)想訪問調(diào)用者的屬性,必須用$this
如果不加,則理解為方法內(nèi)部的一個局部變量.
*/
$a->test();
/******
從生活中的角度來理解$this
女媧造人時,
造了一個"悔恨"的方法
{
抓[自己]頭發(fā)
抽
[自己]
臉
}
世界上的人那么多,
悔恨時,抓誰的頭發(fā)?
抽誰的臉?
張三,李四?
王五?
都不能說明合理的情況
只能理解為"自己"
******/
?>
<?php
/***
====筆記部分====
***/
/****
代碼部分
****/
class
Human
{
public
$name
=
'張三';
public
$gender
=
null;
public
function
__destruct()
{
echo
'死了!<br
/>';
}
}
$e
=
$f
=
$g
=
new
Human();
unset($e);
echo
'unset
e<br
/>';
unset($f);
echo
'unset
f<br
/>';
unset($g);
echo
'unset
g<br
/>';
/*
unset
e
unset
f
死了
unset
g;
*/112-this綁定<?php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/****
代碼部分
****/
class
Human
{
public
$name
=
'lisi';
public
function
who()
{
echo
$this->name;
}
public
function
test()
{
echo
$name;
}
}
$a
=
new
Human();
echo
$a->name,'<br
/>';
//
lisi
$a->who();
/*
和java,c++相比
方法體內(nèi)想訪問調(diào)用者的屬性,必須用$this
如果不加,則理解為方法內(nèi)部的一個局部變量.
*/
$a->test();
/******
從生活中的角度來理解$this
女媧造人時,
造了一個"悔恨"的方法
{
抓[自己]頭發(fā)
抽
[自己]
臉
}
世界上的人那么多,
悔恨時,抓誰的頭發(fā)?
抽誰的臉?
張三,李四?
王五?
都不能說明合理的情況
只能理解為"自己"
******/113-封裝概念<?php
//01.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
面向?qū)ο笕筇卣?
封裝
繼承
多態(tài)
封裝:
***/
/****
代碼部分
****/
/*
class
Human
{
public
$money
=
1000;
}
$lisi
=
new
Human();
echo
$lisi->money,'<br
/>';
//
1000
//
變一下money
$lisi->money
=
500;
echo
$lisi->money,'<br
/>';
//
500
*/
/*
李四的錢,別人問他有多少錢,他就如實說.
別人把他的錢減少,立即減少了.
如果在現(xiàn)實生活中,這個現(xiàn)象顯然不合理,
我們需要把錢保護起來
public
是公共的,即大家都可以來讀取,操作
錢顯然不應(yīng)該是公共的
*/
class
Human
{
private
$money
=
1000;
public
function
showMoney()
{
return
$this->money
*
0.8;
}
}
$lisi
=
new
Human();
/*
在下例中,調(diào)用失敗,因為money是私有和,
在外部,不能夠被調(diào)用
這時,我們就把money
"封起來"了
注意:光封起來,是沒有意義的,因為money這個屬性還得與外界有所交互才行.
*/
//
echo
$lisi->money,'<br
/>';
//
1000
//
你不能直接翻別人口袋,看別人有多少錢.
//
但是,可以問別人有多少錢
/*
把某些重要屬性
封裝起來,然后通過一個開放的接口來操作.
這就實現(xiàn)的對屬性的封裝.
*/
echo
$lisi->showMoney();
?>
<?php
//02.php
/***
====筆記部分====
繼續(xù)來看封裝,在方法上的體現(xiàn)
***/
/****
代碼部分
****/
class
Human
{
private
$money
=
1000;
private
$bank
=
2000;
private
function
getBank($num)
{
$this->bank
-=
$num;
return
$num;
}
public
function
send($much)
{
if($much
>
$this->money
+
$this->bank)
{
return
false;
}
else
if($much
>
$this->money){
$num
=
$much
-
$this->money;
//算算要從銀行取多少錢?
$this->money
+=
$this->getBank($num);
//從銀行取出錢,加到現(xiàn)金里
$this->money
-=
$much;
//
再把錢借給朋友.
return
$much;
}
else
{
//
直接現(xiàn)金借
$this->money
-=
$much;
return
$much;
}
}
public
function
showMoney()
{
return
$this->money;
}
public
function
showBank()
{
return
$this->bank;
}
}
$lisi
=
new
Human();
$m
=
$lisi->send(300);
if($m)
{
echo
'借了',$m,'元<br
/>';
echo
'還剩下',$lisi->showMoney(),'元<br
/>';
}
///
再借
2000
元
$m
=
$lisi->send(2000);
if($m)
{
echo
'借了',$m,'元<br
/>';
echo
'還剩下',$lisi->showMoney(),'元<br
/>';
echo
'銀行還有',$lisi->showBank(),'元,<br
/>';
}
/*
在上個例子中,
借錢者,只知道,借成功了,還是借失敗了.
至于,如果借成功了,lisi是怎么樣把錢湊齊的,
借錢者不會知道lisi也許跑了趟銀行,再把錢湊齊.
就像同學們,只需要
每周一到周五,晚8點到10點來聽課.
至于后面,老師的備課,拉網(wǎng)線,等等,你們不需要知道.
對于一個對象,對外界開放一個接口,
調(diào)用接口時,內(nèi)部進行的操作,不需要讓外界知道.
隱藏了內(nèi)部的一些實現(xiàn)細節(jié).
這是對方法的封裝.
生活中的封裝很常見:
電視機,
開電源
一個動作
[隱藏的內(nèi)部動作:
觸發(fā)顯像管,接線無線電信息,調(diào)頻
等等]
洗衣機:
扔衣服,通電.
[自動加水,洗,漂,脫水]
*/
?>114-private權(quán)限控制<?php
//03.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
權(quán)限修飾符
作用:
用來說明
屬性/方法的權(quán)限特點
寫在
屬性/方法前面
共有3個權(quán)限修飾符
private
私有的
,
保護的最嚴
protected
保護的
public
公共的
,保護的最松
疑問:
public修飾的屬性/方法,可以在哪兒訪問?
private
修飾的屬性/方法,可以在哪兒訪問?
如何判斷屬性/方法
有沒有權(quán)限訪問?
答:看訪問時的位置!
private的屬性/方法,只能在類定義的大括號內(nèi){},才能訪問
public
的屬性,
在任意位置都可以訪問
***/
/****
代碼部分
****/
class
Human
{
public
$mood
=
'';
//
心情,公有
private
$money
=
1000;
//
錢,私有
public
function
showMoney()
{
return
$this->money;
}
private
function
secret()
{
echo
'我小時候偷吃過一塊肉';
}
public
function
tellMe()
{
$this->secret();
}
}
$lisi
=
new
Human();
$lisi->mood
=
'happy';
echo
$lisi->mood,'<br
/>';
//
happy;
//
echo
$lisi->money;
//
調(diào)用位置在54行,在Human類的{}外面
,因此,調(diào)用失敗
//
$lisi->money
=
500;
echo
$lisi->showMoney(),'<br
/>';
/*
showMoney是公共的,在此行可以調(diào)用.
showMoney中的第48號,return
$this->money;
這一句運行的環(huán)境是在
類的{}內(nèi)部,因此有權(quán)限訪問
money屬性
*/
//
$lisi->secret();
//
不可以
$lisi->tellMe();
//
可以,因為是通過第56行,即,類內(nèi)調(diào)用的.
/*
總結(jié):
private權(quán)限控制
只能在類的{}
內(nèi)調(diào)用,
走出了{},
誰也調(diào)不動.
*/
?>
<?php
//04.php
/***
====筆記部分====
看看權(quán)限控制的bug
***/
/****
代碼部分
****/
class
Human
{
private
$money
=
1000;
public
function
getMoney($people)
{
return
$people->money;
}
public
function
setMoney($people)
{
$people->money
-=
500;
}
}
$zhangsan
=
new
Human();
$lisi
=
new
Human();
//
echo
$lisi->money;
//
不行
//
讓李四去打探張三的錢
echo
$lisi->getMoney($zhangsan),'<br
/>';
//
讓李四去改變張三的錢
$lisi->setMoney($zhangsan);
echo
$lisi->getMoney($zhangsan),'<br
/>';
print_r($zhangsan);
/*
奇怪之處在于,
zhangsan的錢,應(yīng)該有zhangsan來調(diào)用getMoney和setMoney才能影響.
但是和我們前一頁面所寫的原則是符合的:
即:
41行調(diào)用
getMoney,有權(quán).
getMoney()
第26行,又在類的{}內(nèi),有權(quán)讀取私有屬性money
44行,調(diào)用setMoney,public
有權(quán)
setMoney()的第30行,修改zhangsan的money,發(fā)生在類的{}內(nèi),有權(quán)操作
*/
?>115-權(quán)限控制的bug(選學)<?php
//05.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/****
代碼部分
****/
class
Human
{
private
$money
=
1000;
public
function
getMoney($people)
{
return
$people->money;
}
public
function
setMoney($people)
{
$people->money
-=
500;
}
}
$zhangsan
=
new
Human();
$lisi
=
new
Human();
//
echo
$lisi->money;
//
不行
//
讓李四去打探張三的錢
echo
$lisi->getMoney($zhangsan),'<br
/>';
//
讓李四去改變張三的錢
$lisi->setMoney($zhangsan);
echo
$lisi->getMoney($zhangsan),'<br
/>';
/*
李四讀取和改變張三的錢,
這如果從生活角度來看,是不合理的
錢私有,是指
"每個對象的錢,針對每個對象私有";
即:張三的錢,由張三->showMoney才能引用.
李四不應(yīng)該有權(quán)直接引用,
或者說,李四->showMoney,也只有權(quán)引用
李四自己的money屬性.
但是,在上面的代碼中,李四卻顯然引用和改為張三的錢.
這是因為:
PHP在實現(xiàn)上,并不是以對象為單位來控制的權(quán)限.
而是以類為單位,來控制的權(quán)限,
所以前一頁,不斷強調(diào)
,類內(nèi),類外,而不是說對象內(nèi),對象外.
因為
類聲明一次,而對象卻可能非常多.
以類為單位,簡化了判斷模型.
第三,從代碼的來看
zend引擎
ce==EG(scope)
這一句判斷的是
調(diào)用者屬性的類
與
執(zhí)行上下文所屬的類
是否相等
在我們判斷中:
$lisi-->類-->Human類
$lisi->setMoney()函數(shù),也在Human類中,
在同一個類內(nèi)部,可以調(diào)用.
這也說明了,確實是以類為單位,以類內(nèi)類外為界限做的判斷
case
ZEND_ACC_PRIVATE:
if
((ce==EG(scope)
||
property_info->ce
==
EG(scope))
&&
EG(scope))
{
return
1;
}
else
{
第四
從其他語言來看一看這個問題.
java
c#,也存在此問題
第五:
從面向?qū)ο蟮慕嵌葋砜荚?/p>
我們的寫法,也有問題
就不應(yīng)該把一個對象,直接傳給一個方法來使用
而應(yīng)該
zhangsan
borrow錢,
應(yīng)該對應(yīng)
lisi
sent錢
即
應(yīng)該盡量的來調(diào)用對象的方法,而不應(yīng)該直接把對象當成參數(shù)給傳過去.
*/
?>116-封裝MySQL類<?php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====簡單MySQL類封裝====
目標:
連接數(shù)據(jù)庫
發(fā)送查詢
對于select型
返回查詢數(shù)據(jù)
關(guān)閉mysql連接
***/
/*
思路:
首先得連接,連接就得有參數(shù).
參數(shù)如何傳?
答:
1可以用配置文件,當網(wǎng)站大了,肯定會有配置文件
2可以通過構(gòu)造函數(shù)傳參
建議用1,但我們目前,僅僅是寫一個簡單類
*/
class
Mysql
{
private
$host;
private
$user;
private
$pwd;
private
$dbName;
private
$charset;
private
$conn
=
null;
//
保存連接的資源
public
function
__construct()
{
//
應(yīng)該是在構(gòu)造方法里,讀取配置文件
//
然后根據(jù)配置文件來設(shè)置私有屬性
//
此處還沒有配置文件,就直接賦值
$this->host
=
'localhost';
$this->user
=
'root';
$this->pwd
=
'111111';
$this->dbName
=
'test';
//
連接
$this->connect($this->host,$this->user,$this->pwd);
//
切換庫
$this->switchDb($this->dbName);
//
設(shè)置字符集
$this->setChar($this->charset);
}
//
負責連接
private
function
connect($h,$u,$p)
{
$conn
=
mysql_connect($h,$u,$p);
$this->conn
=
$conn;
}
//
負責切換數(shù)據(jù)庫,網(wǎng)站大的時候,可能用到不止一個庫
public
function
switchDb($db)
{
$sql
=
'use
'
.
$db;
$this->query($sql);
}
//
負責設(shè)置字符集
public
function
setChar($char)
{
$sql
=
'set
names
'
.
$char;
$this->query($sql);
}
//
負責發(fā)送sql查詢
public
function
query($sql)
{
return
mysql_query($sql,$this->conn);
}
//
負責獲取多行多列的select
結(jié)果
public
function
getAll($sql)
{
$list
=
array();
$rs
=
$this->query($sql);
if(!$rs)
{
return
false;
}
while($row
=
mysql_fetch_assoc($rs))
{
$list[]
=
$row;
}
return
$list;
}
//
獲取一行的select
結(jié)果
public
function
getRow($sql)
{
$rs
=
$this->query($sql);
if(!$rs)
{
return
false;
}
return
mysql_fetch_assoc($rs);
}
//
獲取一個單個的值
public
function
getOne($sql)
{
$rs
=
$this->query($sql);
if(!$rs)
{
return
false;
}
$row
=
mysql_fetch_row($rs);
return
$row[0];
}
public
function
close()
{
mysql_close($this->conn);
}
}
echo
'<pre>';
$mysql
=
new
Mysql();
print_r($mysql);
/*
$sql
=
"insert
into
stu
values
(20,'object','99988')";
if($mysql->query($sql))
{
echo
'query成功';
}
else
{
echo
'失敗';
}
*/
echo
'<br
/>';
$sql
=
'select
*
from
stu';
$arr
=
$mysql->getAll($sql);
print_r($arr);
//
查詢16號學員
$sql
=
'select
*
from
stu
where
id=16';
print_r($mysql->getRow($sql));
//
查詢共有多少個學生
$sql
=
'select
count(*)
from
stu';
print_r($mysql->getOne($sql));
/*
到此,一個簡單的mysql封裝類,完成.
改進:
insert
update操作,都需要大量拼接字符串.
能否給定一個數(shù)組,數(shù)組鍵->列
,數(shù)組值->列的值
然后自動生成
insert
語句!
*/117-繼承概念<?php
//01.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
繼承:
是指以一個類為父類,另一個類可以做為其子類,
子類在繼承了父類的屬性/方法的基礎(chǔ)上,
進一步增添或修改.
***/
/****
代碼部分
****/
//
定義3個類,
人類,
學生類,律師類
class
Human
{
private
$height
=
160;
public
function
cry()
{
echo
'5555<br
/>';
}
}
class
Stu
{
private
$height
=
170;
public
$snun
=
'00134';
public
function
cry()
{
echo
'59啊59<br
/>';
}
public
function
study()
{
echo
'good
good
study,
day
day
up<br
/>';
}
}
/*
老友記
long
time
no
see
you
don't
bird
me,I
don't
bird
you!
*/
class
Lawer
{
private
$height
=
'180';
public
$area
=
'經(jīng)濟案件';
public
function
cry()
{
echo
'5555<br
/>';
}
public
function
bianhu()
{
echo
'我的當事人是無罪的<br
/>';
}
}
$zhoukou
=
new
Human();
$zhoukou->cry();
$xiaoming
=
new
Stu();
$xiaoming->cry();
$xiaoming->study();
$lizhuang
=
new
Lawer();
$lizhuang->cry();
$lizhuang->bianhu();
/****
思考:
1:
學生和律師
歸根結(jié)底還是人!
自然,人的屬性和方法,自然就有
2:學生和律師,雖然是人,但比最原始的人,
又多了一些屬性和方法.
而我們目前寫的3個類,
完成了第2點:
即有原始人的屬性,又有學生/律師的獨特屬性
但是,沒有很好的利用上第1點:
即:既然是人,那默認就應(yīng)該有人的屬性,何必再重新聲明一遍???
這里的代碼,就已經(jīng)冗余!
如何達到
學生/律師
默認就有人的屬性,達到代碼的重用和簡潔?
答:
繼承
****/
?>
<?php
//02.php
/***
====筆記部分====
繼承
語法:
extends
子類
extends
父類
{
}
注意點:
子類
只能繼承自
一個父類
不能這樣寫:
subClass
extends
Dog,Cat,Pig
{
}
***/
/****
代碼部分
****/
class
Human
{
private
$height
=
160;
public
function
cry()
{
echo
'5555<br
/>';
}
}
//
再聲明一個學生類,學生本質(zhì)上還是人
//
只不過是人類中,稍微特殊一點的一個群體.
//
即:人類的基礎(chǔ)上,衍生出學生類.
//
可以讓學生類
繼承自
人類
class
Stu
extends
Human{
}
$zhoukou
=
new
Human();
$zhoukou->cry();
/**/
$lily
=
new
Stu();
$lily->cry();
$lily->laugh();
/*
思考:
在學生類中
cry
與
laugh方法
都沒定義
為什么cry方法調(diào)用成功
laugh方法調(diào)用失敗!
答:因為Stu類
繼承自
Human類
現(xiàn)實中,繼承的例子更多.
你同事高帥富,某天開了個寶馬.
他沒有寶馬,但是他爹有寶馬.
*/
?>118-私有屬性的繼承(稍難)<?php
//03.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
繼承了哪些東西?
子類可以做什么擴充?
構(gòu)造函數(shù)如何繼承的?
私有屬性/方法如何繼承?
***/
/****
代碼部分
****/
//
class
Human
{
private
$wife
=
'小甜甜';
public
function
cry()
{
echo
'5555<br
/>';
}
}
class
Stu
extends
Human{
public
function
subtell()
{
echo
$this->wife;
}
}
$lisi
=
new
Stu();
$lisi->cry();
//
5555
$lisi->subtell();
//
出錯如下
/*
未定義的屬性,wife屬性
Undefined
property:
Stu::$wife
in
D:\www\1108\03.php
on
line
44
問:父類不是有wife屬性嗎?
為什么沒繼承過來?
答:
私有的屬性,可以理解不能繼承.
(其實能繼承過來,只不過無法訪問)
public
protected
private中,
public
protected
都可以繼承,并擁有訪問和修改的權(quán)限
這就好比說,家產(chǎn)已經(jīng)繼承了,愿意賣就賣,愿意改就改.
而私有的,就像先祖的牌位,繼承下來
但是無權(quán)動,只能供著.
*/
?>
<?php
//04.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
繼承時,繼承來Protcted/public
屬性/方法
完全繼承過來,屬性子類.
繼承來
父類private屬性/方法,
但不能操作
***/
/****
代碼部分
****/
class
Human
{
//
private
$wife
=
'小甜甜';
public
$age
=
22;
public
function
cry()
{
echo
'5555<br
/>';
}
public
function
pshow()
{
echo
$this->wife,'<br
/>';
}
}
class
Stu
extends
Human{
private
$wife
=
'鳳姐';
public
$height
=
180;
public
function
sshow()
{
parent::pshow();
echo
$this->wife,'<br
/>';
}
}
$lisi
=
new
Stu();
//
print_r($lisi);
$lisi->sshow();
//
???
/*
根據(jù)圖來思考:
如果把Stu類中的
wife=鳳姐去掉,什么效果?
//
未定義屬性
如果把Human類中的
wife=小甜甜去掉,什么效果?
//
無權(quán)訪問
*/
?>119-公共及保護屬性和方法的繼承<?php
//05.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
子類繼承父類的屬性/方法,可以修改或增加
***/
/****
代碼部分
****/
class
sixty
{
protected
$wine
=
'1斤';
public
function
play()
{
echo
'談理想<br
/>';
}
}
class
nine
extends
sixty{
public
function
play()
{
echo
'玩網(wǎng)游,宅!<br
/>';
}
public
function
momo()
{
echo
'妹子,認識一下<br
/>';
}
public
function
showW()
{
echo
$this->wine,'<br
/>';
}
}
$s9
=
new
nine();
$s9->showW();
echo
'<br
/>';
//
父類有的,繼承過來
$s9->play();
//
父類有的,繼承過來,可以修改/覆蓋(overide).
$s9->momo();
//
父類沒有,可以添加
/***
上面所說的繼承過來的大環(huán)境,
是指
protected
/public
**/
?>
<?php
//06.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
繼承時的權(quán)限變化
繼承自父類的屬性/方法
權(quán)限只能越來越寬松或不變,不能越來越嚴格.
***/
/****
代碼部分
****/
class
Human
{
public
function
cry()
{
echo
'555<br
/>';
}
}
class
Stu
extends
Human{
protected
function
cry()
{
echo
'5959<br
/>';
}
}
/*
Fatal
error:
Access
level
to
Stu::cry()
must
be
public
(as
in
class
Human)
in
D:\www\1108\06.php
on
line
36
子類的cry比父類的cry方法,權(quán)限要嚴格.
這不行,繼承時,權(quán)限只能越來越寬松或不變,不能越來越嚴格.
*/
?>120-構(gòu)造函數(shù)的繼承<?php
//07.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/****
構(gòu)造方法的繼承
答:
構(gòu)造方法也是可以繼承的,
而且繼承的原則和普通方法一樣.
進而,如果子類也聲明構(gòu)造函數(shù),則父類的構(gòu)造函數(shù),被覆蓋了!
如果父類構(gòu)造函數(shù)被覆蓋了,自然,只執(zhí)行子類中新的構(gòu)造函數(shù).
引發(fā)一個問題:
如果是一個數(shù)據(jù)庫操作類,或者model類
我們肯定是要繼承過去再使用,不能直接操作model類.
而model類的構(gòu)造函數(shù),又做了許多初始化工作.
我重寫的model類的構(gòu)造函數(shù)之后,導致初始化工作完不成了,怎么辦?
答:
如果子類繼承時,子類有構(gòu)造函數(shù),保險一點,調(diào)用
parent::__construct
這一點和java的面向?qū)ο?也有不同.
在java中,實例化子類時,
父類的構(gòu)造函數(shù)運行,且先運行
然后運行子類的構(gòu)造函數(shù)
另外:
java中構(gòu)造函數(shù)不是
__construct(),而是和類名相同的方法理解為構(gòu)造函數(shù).
在一些比較教材或者,老的代碼中,你也有可能這種情況.
即
與類名相同的函數(shù)做構(gòu)造函數(shù)這是PHP4時代的殘留.
請記住,你不要這樣寫
****/
class
Human
{
public
function
__construct(){
echo
'呱呱墜地!<br
/>';
}
}
class
Stu
extends
Human
{
}
$ming
=
new
Stu();
//
呱呱墜地,這說明構(gòu)造函數(shù)也是可以繼承的
class
King
extends
Human
{
public
function
__construct()
{
echo
'紅光滿屋,終日不散<br
/>';
}
}
$zhu
=
new
King();
echo
'<hr
/>';
class
Mysql
{
protected
$conn
=
NULL;
public
function
__construct()
{
$this->conn
=
mysql_connect('localhost','root','111111');
}
public
function
query($sql)
{
return
mysql_query($sql,$this->conn);
}
}
/*
$mysql
=
new
Mysql();
var_dump($mysql->query('use
test'));
//
true,query成功
*/
class
MyDb
extends
Mysql{
public
function
__construct()
{
//
如果子類繼承時,有構(gòu)造函數(shù),保險一點
parent::__construct();
//
然后再寫自己的業(yè)務(wù)邏輯
}
public
function
autoInsert()
{
return
$this->query('use
test');
}
}
$mydb
=
new
MyDb();
//
看看問題出在哪兒?
var_dump($mydb->autoInsert());
?>121-public_protected_private權(quán)限控制詳解<?php
//02.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
private
protected
public
三者的區(qū)別
private
protected
public
本類內(nèi)
Y
Y
Y
子類內(nèi)
N
Y
Y
外部
N
N
Y
注意:
在java中,如果屬性/方法前面不寫任何參數(shù)
即public/protected/private都不寫,也是可以的,friendly
在PHP中,如果public/protected/private
都不寫,
則理解為
public
建議養(yǎng)成好習慣,不要不寫
***/
/****
代碼部分
****/
class
Human
{
private
$name
=
'zhangsan';
protected
$money
=
3000;
public
$age
=
28;
public
function
say()
{
echo
'我叫',$this->name,'<br
/>';
echo
'我有',$this->money,'元錢<br
/>';
echo
'我今年',$this->age,'歲';
}
}
class
Stu
extends
Human
{
private
$friend
=
'小花';
public
function
talk()
{
echo
'我叫',$this->name,'<br
/>';
echo
'我有',$this->money,'元錢<br
/>';
echo
'我今年',$this->age,'歲<br
/>';
}
}
$ming
=
new
Stu();
echo
$ming->age,'<br
/>';
//
28
//
下行錯,因為類外不能調(diào)用private
//
echo
$ming->friend;
//
下行錯,因為類外不能調(diào)用protected屬性
//
echo
$ming->money;
/*
總結(jié):
public
可以在類外調(diào)用,權(quán)限最為寬松
protected和
private不能在類外調(diào)用
??
public
在類內(nèi)調(diào)用行不行
答:當然行,類外都可以,權(quán)限很寬松,類內(nèi)自然沒問題.
*/
/*
下一行執(zhí)行時
Notice:
Undefined
property:
Stu::$name
in
D:\www\1109\02.php
on
line
44
我有3000元錢
我今年28歲
分析原因:
Undefined
property:
Stu::$name
這是說明:stu對象
沒有name屬性
但昨天說,私有的不是可以繼承嗎?
是可以繼承過來,但系統(tǒng)有標記,標記其為父類層面的私有屬性.
因此無權(quán)調(diào)用,導致此錯發(fā)生.
可以分析出:
protected
可以在
子類內(nèi)訪問
??
protected能在子類訪問,本類內(nèi)能否訪問?
答:當然可以
*/
$ming->talk();
echo
'<hr
/>';
$yuanmou
=
new
Human();
$yuanmou->say();
?>122-精講多態(tài)PHP與java對比講解<?php
//03.php
/****
燕十八
公益PHP講堂
論
壇:
http://www.zixue.it
微
博:
/Yshiba
YY頻道:
88354001
****/
/***
====筆記部分====
public
class
PolyTest
{
public
static
void
main(String[]
args)
{
Light
light
=
new
Light();
RedGlass
rg
=
new
RedGlass();
BlueGlass
bg
=
new
BlueGlass();
light.ons(rg);
light.ons(bg);
//
I
want
to
show
blue
light;
}
}
class
Light
{
public
void
ons(RedGlass
red)
{
red.display();
}
}
class
RedGlass
{
public
void
display()
{
System.out.println("red
light");
}
}
class
BlueGlass
{
public
void
display()
{
System.out.println("BlueGlass");
}
}
這樣一段代碼,在java中
編譯通不過.
原因是:
public
void
ons(RedGlass
red)
{
red.display();
}
ons方法,
指定了
接收的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025福建廈門夏商集團有限公司招聘2人模擬試卷附答案詳解(模擬題)
- 2025年宿州市中醫(yī)醫(yī)院招聘36人考前自測高頻考點模擬試題完整參考答案詳解
- 企業(yè)管理策略咨詢方案
- 鉆井公司考試試題及答案
- 2025年湖南軌道匯能發(fā)展有限公司第二次招聘模擬試卷及完整答案詳解1套
- 書店營銷員營銷方案
- 什么是小區(qū)文明施工方案
- 倉庫芯片管理制度范本
- 100字運動會發(fā)言稿
- 2025北京三支一扶招聘473人模擬試卷及答案詳解(全優(yōu))
- 新課標下的小學語文跨學科教學模式探討
- 2025年物聯(lián)網(wǎng)安裝調(diào)試員(高級)技能鑒定考試題庫
- 高一上冊第三單元《永遇樂 京口北固亭懷古》
- 店鋪共享合伙人模式
- 2025-2030年中國山葵制品行業(yè)運行現(xiàn)狀及發(fā)展前景分析報告
- 銀行支行行長2025年度工作計劃
- 二零二五年度污水運輸與污水處理廠合作運營合同
- 2025年上教版八年級地理上冊月考試卷
- 貿(mào)易安全課件
- 中職對口高考-機械類專業(yè)綜合模擬卷( 湖北適用) 第5卷(答案版)
- 部編六年級上冊快樂讀書吧《童年》測試題(3份)(有答案)
評論
0/150
提交評論