第一篇:傳智播客 韓順平 php從入門到精通 61-78講面向?qū)ο笳n堂筆記
php面向?qū)ο缶幊?提出一個(gè)問題?
張老太養(yǎng)了兩只貓貓:一只名字叫小白,今年3歲,白色。還有一只叫小花,今年100歲,花色。請編寫一個(gè)程序,當(dāng)用戶輸入小貓的名字時(shí),就顯示該貓的名字,年齡,顏色。如果用戶輸入的小貓名錯(cuò)誤,則顯示張老太沒有這只貓貓。數(shù)組<--->對象
array(1,56,90,100)->隱藏問題array(對象,對象。。)【數(shù)組對象】 首先我們用現(xiàn)有的知識(shí)來完成這個(gè)案例:
$cat1_name=”小白”;
$cat1_age=3;
$cat1_color=”白色”;
//變量是分開.$cat2_name=”小花”;
$cat2_age=100;
$cat2_color=”花色”;?>
我們能不能把屬于同一事物的變量,統(tǒng)一管理? 解決之道->對象 快速體驗(yàn)案例:
//這就是一個(gè)類(貓類)class Cat{
//屬性
public $name;
public $age;
public $color;}
//創(chuàng)建一只貓 $cat1=new Cat();//給這只貓賦值.(具體各個(gè))$cat1->name=“小白”;$cat1->age=3;$cat1->color=“白色”;$cat2=new Cat();$cat2->name=“小花”;$cat2->age=100;$cat2->color=“顏色”;//如果我們找到一只貓,只要找到 $cat1, 那么該變量所有相關(guān)的屬性都通通的找到 $findCatName=“小花”;
if($cat2->name==$findCatName){
echo $cat2->name.“||”.$cat2->age.“||”.$cat2->color;} ?>
我們這里說明一下類和對象的關(guān)系(細(xì)節(jié)后面逐步展開)
總結(jié)幾句話:
①
類是抽象的,代表一類事物 ②
對象是具體,是類的一個(gè)具體實(shí)例 ③
類是對象的模板, 對象是類的一個(gè)個(gè)體實(shí)例
php面向?qū)ο缶幊?/p>
成員屬性的說明
1.成員屬性是從某個(gè)事物提取出的,它可以是基本數(shù)據(jù)類型(整數(shù)、小數(shù)、字符、布爾),也可以是復(fù)合數(shù)據(jù)類型(數(shù)組、對象)
class Cat{ public $name;public $age;}
//創(chuàng)建對象
$cat1=new Cat;
$cat1=new Cat();?>
2.怎樣訪問一個(gè)成員屬性(其它成員屬性是public)基本語法是 $對象名->屬性名;
?如果一個(gè)文件,專門用于定義類,則命名規(guī)范應(yīng)當(dāng)這樣
類名.class.php 分析對象在內(nèi)存中存在的形式 //定義一個(gè)人類 class Person{ public $name;public $age;} $a=new Person();$a->name=“小明”;$a->age=20;//把a(bǔ)變量(對象),賦給$b $b=$a;echo $a->name.“
”;echo $b->name.“
”;
再次說明: $a=78;//$b=$a;$b=&$a;$b=$b+8;echo $a.“||”.$b;
如果給一個(gè)函數(shù)傳遞一個(gè)對象,實(shí)際上是傳遞的一個(gè)地址.//看下面的一段代碼: class Person{
public $name;public $age;} $p1=new Person();$p1->name=“韓順平”;$p1->age=33;//函數(shù)接收對象時(shí)候,究竟是傳入值,還是地址(?。?
function test1($p){ $p->name=“小明”;} test1($p1);echo $p1->name;分析圖
如果給函數(shù)傳遞的是基本數(shù)據(jù)類型(整數(shù)、小數(shù)、布爾、字符),究竟傳遞的是什么? 結(jié)論 : 在默認(rèn)的情況下是傳遞的值,如果你希望傳入地址 function test(&$變量....){ }
在php中如果,給一個(gè)函數(shù)傳遞的是數(shù)組,則默認(rèn)情況下是傳值(拷貝了新的數(shù)組),如果希望傳入地址,則應(yīng)當(dāng),&$數(shù)組名 學(xué)生問題?
$a1=array(1,3,900);$a2=array(56,90,100);
$arr=array($a1,$a2);
foreach($arr as $k=>$v){
echo “$k=$v”;} ?>
成員方法的講解 函數(shù)和成員方法關(guān)系:
當(dāng)我們把一個(gè)函數(shù)寫到某個(gè)類中,則該函數(shù)可以稱成員方法:
我們有這樣一個(gè)需求;希望人可以說話, 做算術(shù)題.......,這樣就需要使用到成員方法: ①添加speak 成員方法,輸出我是一個(gè)好人
②添加jisuan成員方法,可以計(jì)算從 1+..+1000的結(jié)果
③修改jisuan成員方法,該方法可以接收一個(gè)數(shù)n,計(jì)算 1+..+n 的結(jié)果
④添加add 成員方法,可以計(jì)算兩個(gè)數(shù)的和 成員方法的基本語法:
訪問修飾符號(hào) function 函數(shù)名(參數(shù)列表){
//函數(shù)體
//return 語句;}
class Person{
public $name;
public $age;
public function speak(){
echo “我是一個(gè)好人!”;
}
public function count1(){
$res=0;
for($i=1;$i<=1000;$i++){
$res+=$i;
}
//return 究竟到什么地方去?誰調(diào)用,就返回給誰
return $res;
}
//修改jisuan成員方法,該方法可以接收一個(gè)數(shù)n,計(jì)算 1+..+n 的結(jié)果
public function count2($n){
$res=0;
for($i=0;$i<=$n;$i++){
$res+=$i;
}
return $res;
}
//添加add 成員方法,可以計(jì)算兩個(gè)數(shù)的和
public function add($num1,$num2){
return $num1+$num2;
}
}
//如何使用函數(shù)
//1.創(chuàng)建一個(gè)人
$p1=new Person();
//通過對象去訪問,調(diào)用成員方法.//這里強(qiáng)調(diào),調(diào)用成員方法和調(diào)用普通函數(shù)的機(jī)制,仍然不變
$p1->speak();
//讓這個(gè)人做算術(shù)題
$res=$p1->count1();
echo '計(jì)算結(jié)果是='.$res;
//讓這個(gè)人可以接收一個(gè)數(shù),然后計(jì)算
echo “計(jì)算結(jié)果是=”.$p1->count2(100);
echo “計(jì)算結(jié)果是=”.$p1->count2(100);
echo “計(jì)算結(jié)果是=”.$p1->count2(100);
echo “23+89=”.$p1->add(23,89);?>
成員方法的細(xì)節(jié)
我們在實(shí)際開發(fā),其實(shí)通常是這樣來使用類
Person.class.php < ?php
class Person{
//成員屬性
public $name;
public $age;
//成員方法
public function speak(){
echo “我是一個(gè)好人!”;
}
public function count1(){
$res=0;
for($i=1;$i<=1000;$i++){
$res+=$i;
}
//return 究竟到什么地方去?誰調(diào)用,就返回給誰
return $res;
}
//修改jisuan成員方法,該方法可以接收一個(gè)數(shù)n,計(jì)算 1+..+n 的結(jié)果
public function count2($n){
$res=0;
for($i=0;$i<=$n;$i++){
$res+=$i;
}
return $res;
}
//添加add 成員方法,可以計(jì)算兩個(gè)數(shù)的和
public function add($num1,$num2){
return $num1+$num2;
}
//添加一個(gè)新的方法,可以判斷三個(gè)數(shù)最大的數(shù)
public function findMax($arr){
//這里仍然可以寫算法
//從$arr數(shù)組中,找到最大的數(shù).//1.假設(shè)數(shù)組的第一個(gè)數(shù)就是最大的數(shù)
$maxVal=$arr[0];
//2.最大數(shù)的下標(biāo)是
$maxIndex=0;
//開始循環(huán)的比較
for($i=1;$i //這個(gè)條件說明,maxVal不是最大 if($maxVal<$arr[$i]){ //調(diào)整 $maxVal=$arr[$i]; $maxIndex=$i; } } return $maxVal; } } ?> Exercise01.php < ?php //引入類文件 require_once ?Person.class.php?; //創(chuàng)建對象 $p1=new Person(); //調(diào)用$p1的各個(gè)方法 $p1->speack(); $p1->count1();..?> 案例:編寫一個(gè)函數(shù)(以面向?qū)ο蟮姆绞介_發(fā)),從網(wǎng)頁輸入一個(gè)整數(shù)打印出對應(yīng)的金子塔: 當(dāng)我們學(xué)習(xí)完成員方法后,我們的類定義就完善一步了: 1.設(shè)計(jì)計(jì)算機(jī)類,要求如下: 屬性:品牌,顏色,cpu型號(hào),內(nèi)存容量,硬盤大小,價(jià)格,工作狀態(tài) 方法: 打開,關(guān)閉,休眠(表示)創(chuàng)建一個(gè)計(jì)算機(jī)對象,調(diào)用打開,關(guān)閉方法.php面向?qū)ο缶幊?/p> 構(gòu)造方法 class Person{ public $name; public $age;} $p1=new Person();//再給屬性賦值 $p1->name=”宋江”;$p1->age=33; //需求在創(chuàng)建一個(gè)人對象時(shí)候,我就初始化 name 和 age;->構(gòu)造方法 我們快速入門: class Person{ public $name; public $age; public function __construct(){ echo “我是構(gòu)造方法”; } //業(yè)務(wù)代碼要放在成員方法 public function findPerson(){ } } $p1=new Person();?構(gòu)造方法沒有返回值, 它是自動(dòng)被調(diào)用 2.在php 5 中一個(gè)類可以同時(shí)有兩種形式的構(gòu)造方法 __construct()和類名(), 當(dāng)兩個(gè)同時(shí)存在的時(shí)候,優(yōu)先調(diào)用__construct(), 請大家以后使用__construct() this的理解 class Person{ public $name;public $age; //這個(gè)就是構(gòu)造方法,php5獨(dú)有 public function __construct($iname,$iage){ //$name認(rèn)為$name是一個(gè)新的變量 //$name=$iname; //$age=$iage; $this->name=$iname; $this->age=$iage; echo “我是構(gòu)造方法”;} } $p1=new Person(“張清”,90);echo “hello-”.$p1->name;$p2=new Person(“宋江”,33);echo “aa-”.$p2->name;$this 理解圖: ? 1.$this 本質(zhì)可以理解就是這個(gè)對象的地址 2.哪個(gè)對象使用到$this, 就是哪個(gè)對象地址 3.$this不能在類外部使用.構(gòu)造方法的注意事項(xiàng) (1)一旦自定義了一個(gè)構(gòu)造函數(shù),默認(rèn)的 構(gòu)造函數(shù)就被覆蓋了,這時(shí)在創(chuàng)建對象的時(shí)候就要使用自定義的構(gòu)造函數(shù).(2)一個(gè)類只能有一個(gè)構(gòu)造函數(shù).(不能重載)構(gòu)造方法的8點(diǎn)說明: ①構(gòu)造方法名和類名相同(php4版),php5版的構(gòu)造方法 名可以和類名相同,也可以是__construct()②構(gòu)造方法沒有返回值 ③主要作用是完成對新對象的初始化,并不是創(chuàng)建對象本身。④在創(chuàng)建新對象后,系統(tǒng)自動(dòng)的調(diào)用該類的構(gòu)造方法 ⑤一個(gè)類有且只有一個(gè)構(gòu)造方法,在php5后雖然__construct()和類名()可以共存,但是實(shí)際上也只能使用一個(gè)。 ⑥如果沒有給類自定義構(gòu)造方法,則該類使用系統(tǒng)默認(rèn)的構(gòu)造方法。class Cat{ funciton __construt($name){ echo “ok”;} } $cat1=new Cat(); ⑦如果給類自定義了構(gòu)造方法,則該類的默認(rèn)構(gòu)造方法被覆蓋。⑧構(gòu)造方法的默認(rèn)訪問修飾符是public 析構(gòu)方法 析構(gòu)方法的作用主要用于,釋放資源(比如釋放數(shù)據(jù)庫的鏈接,圖片資源...銷毀某個(gè)對象..)快速入門 class Person{ public $name; public $age; public $conn; //構(gòu)造方法 public function __construct($name,$age){ $this->name=$name; $this->age=$age; //打開一個(gè)$conn鏈接數(shù)據(jù)庫的資源 } //寫一個(gè)析構(gòu)方法 __ 是兩個(gè)下劃線 function __destruct(){ echo $this->name.“銷毀資源關(guān)閉數(shù)據(jù)庫.. } } $p1=new Person(“賈寶玉”,16); $p2=new Person(“林黛玉”,14);?> 運(yùn)行代碼我們得出: 1.析構(gòu)方法會(huì)自動(dòng)調(diào)用 2.析構(gòu)方法主要用于銷毀資源 3.析構(gòu)方法調(diào)用順序是,先創(chuàng)建的對象后被銷毀 4.析構(gòu)方法什么時(shí)候被調(diào)用(1)當(dāng)程序(進(jìn)程結(jié)束)退出時(shí) (2)當(dāng)一個(gè)對象稱為垃圾對象的時(shí)候,該對象的析構(gòu)方法也會(huì)被調(diào)用,(3)所謂垃圾對象,就是指,沒有任何變量再引用它.(4)一旦一個(gè)對象成為垃圾對象,析構(gòu)方法就會(huì)立即調(diào)用 示意圖: 小結(jié): ①php5加入的的析構(gòu)方法function __destruct()②析構(gòu)方法沒有返回值 ③主要作用是釋放資源的操作,并不是銷毀對象本身。④在銷毀對象前,系統(tǒng)自動(dòng)的調(diào)用該類的析構(gòu)方法 ⑤一個(gè)類最多只有一個(gè)析構(gòu)方法。 更新時(shí)間:2013年01月03日17時(shí)03分 來源: 靜態(tài)變量 提出一個(gè)問題: 說,有一群小孩在玩堆雪人,不時(shí)有新的小孩加入, 請問如何知道現(xiàn)在共有多少人在玩?請使用面向 對象的思想,編寫程序解決。思路: 1.使用全局變量 * 什么是全局變量, 在程序中,都可以使用的變量稱為全局變量.當(dāng)我們了解全局變量后,我們來看看如何解決問題? //定義,完游戲的全局變量 global $global_nums; //賦值 $global_nums=0; class Child{ public $name; function __construct($name){ $this->name=$name; } public function join_game(){ //聲明一下使用全局變量 global $global_nums; $global_nums+=1; echo $this->name.“加入堆雪人游戲”; } } //創(chuàng)建三個(gè)小孩 $child1=new Child(“李逵”); $child1->join_game(); $child2=new Child(“張飛”); $child2->join_game(); $child3=new Child(“唐僧”); $child3->join_game(); //看看有多少人玩游戲 echo “ 2.使用靜態(tài)變量 靜態(tài)的變量的基本用法 1.在類中定義靜態(tài)變量 [訪問修飾符] static $變量名;2.如何訪問靜態(tài)變量 如果在類中訪問 有兩種方法self::$靜態(tài)變量名 , 類名::$靜態(tài)變量名 如果在類外訪問: 有一種方法類名::$靜態(tài)變量名 3.靜態(tài)變量存在方式 解法: class Child{ public $name; //這里定義并初始化一個(gè)靜態(tài)變量 $nums public static $nums=0; function __construct($name){ $this->name=$name; } public function join_game(){ //self::$nums使用靜態(tài)變量 self::$nums+=1; echo $this->name.“加入堆雪人游戲”; } } //創(chuàng)建三個(gè)小孩 $child1=new Child(“李逵”); $child1->join_game(); $child2=new Child(“張飛”); $child2->join_game(); $child3=new Child(“唐僧”); $child3->join_game(); //看看有多少人玩游戲 echo “ ? 靜態(tài)方法 需求: 當(dāng)我們操作靜態(tài)變量的時(shí)候,我們可以考慮使用靜態(tài)方法,比如統(tǒng)計(jì)所有學(xué)生交的學(xué)費(fèi) 在我們編程中,我們往往使用靜態(tài)方法去操作靜態(tài)變量.靜態(tài)方法的特點(diǎn) 1.靜態(tài)方法去操作靜態(tài)變量 2.靜態(tài)方法不能操作非靜態(tài)變量.這里請注意 : 普通的成員方法,既可以操作非靜態(tài)變量,也可以操作靜態(tài)變量 ? php面向?qū)ο缶幊痰娜筇卣?/p> ① 封裝 ② 繼承 ③ 多態(tài) 抽象 class Account { public $blance; public $no; public function qun(){ } public function cun(){ } } ? 封裝 那么在php中如何實(shí)現(xiàn)這種類似的控制呢?請大家看一個(gè)小程序.(visit1.php),不能隨便查看人的年齡,工資等隱私...class Person{ public $name; private $age; private $salary; function __construc($name,$age,$salary){ $this->name=$name; $this->age=$age; $this->salary=$salary } } php提供了三種訪問控制符號(hào).有三種 1.public 表示全局,可以在本類,類外部,子類中使用 2.protected 表示受到保護(hù),可以在本類, 子類中使用 3.private 表示私有, 只能在本類使用 這三個(gè)控制修飾符號(hào)可以對屬性和方法修飾 1.如果一個(gè)方法沒有訪問修飾符,則默認(rèn)是public 2.屬性必須指定訪問修飾符 ?方法之間可以互相調(diào)用.但是需要使用 $this引用 function test11(){ $this->test12(); } protected function test12(){ echo “test12 hello”; } 舉例說明: class Person{ public $name; protected $age; private $salary; function __construct($name,$age,$salary){ $this->name=$name; $this->age=$age; $this->salary=$salary; } //成員方法 function showInfo(){ //這里說明在本類中可以使用 public protected 和private 修飾的變量.echo $this->name.“||”.$this->age.“||”.$this->salary; } } //創(chuàng)建一個(gè)人 $p1=new Person(“孫悟空”,30,1000); echo $p1->name;//可以 echo $p1->age;//報(bào)錯(cuò) echo $p1->salary;//報(bào)錯(cuò).?我們現(xiàn)在就想去訪問protected 變量或者 private 變量, 通常的做法是提供 public 函數(shù)去訪問這些變量.形式是 public function setXxx($val){ } public function getXxx(){ } public function showInfo(){ } public protected private 可以修飾屬性和方法 (1)查看薪水(private)//獲取這個(gè)人的薪水 public function getSalary($user,$pass){ if($user==“shunping” && $pass=“123”){ return $this->salary; }else{ return “sorry,你無法看”; } }(2)修改人的年齡 提供了兩個(gè)函數(shù).//修改年齡,對輸入的值,進(jìn)行校驗(yàn).public function setAge($age){ if($age>1 && $age<120){ $this->age=$age; }else { echo “年齡范圍不對”; } } //查看年齡 public function getAge(){ return $this->age; } 還有一種形式, 通過一對 __set 和 __get方法來操作我們的變量,不推薦.class A{ private $n1; private $n2; private $n3; //使用__set 方法來管理所有的屬性 public function __set($pro_name,$pro_val){ $this->pro_name=$pro_val; } //使用__get 可以獲取所有的屬性值 public function __get($pro_name){ if(isset($pro_name)){ return $this->pro_name; }else{ return null; } } } $a1=new A(); $a1->n1=“hello”; echo $a1->n1; $a1->n2=890; echo “||”.$a1->n2; 可以直接寫一個(gè)方法了操作變量 class Peron{ protected n1; private $n2; function showInfo($n1){ $this->n1=$n1; echo $this->n1.”||”$this->n2;} } ? 為什么需要繼承 //應(yīng)用場景開發(fā)一套學(xué)生管理系統(tǒng)(Pupil, Graduate ,...) //小學(xué)生類 class Pupil{ public $name; protected $age; protected $grade; public function showInfo(){ echo $this->name.“||”.$this->age; } public function tesing(){ echo “ 小學(xué)生考試..”; } } //研究生類 class Graduate{ public $name; protected $age; protected $grade; public function showInfo(){ echo $this->name.“||”.$this->age; } public function tesing(){ echo “研究生考試..”; } } 從上面的代碼我們看出,代碼的復(fù)用性不高,同時(shí)也會(huì)讓管理代碼成本增高.? 解決之道(繼承); 現(xiàn)在我們使用繼承對上面的代碼,進(jìn)行改寫.代碼: //應(yīng)用場景開發(fā)一套學(xué)生管理系統(tǒng)(Pupil, Graduate ,...) //父類 class Stu{ public $name; protected $age; protected $grade; public function showInfo(){ echo $this->name; } } //子類 class Pupil extends Stu{ public function testing(){ echo “ 小學(xué)生考試..”; } } class Graduate extends Stu{ public function testing(){ echo “研究生考試..”; } } //創(chuàng)建學(xué)生 $stu1=new Pupil(); $stu1->name=“小明”; $stu1->testing(); $stu1->showInfo(); //創(chuàng)建一個(gè)研究生 $stu2=new Graduate(); $stu2->name=“老明”; $stu2->testing(); $stu2->showInfo(); ?從上面的代碼我們可以看出: 所謂繼承就是一個(gè)子類通過 extends 父類 把父類的(public / protected)屬性和(public / protected)方法繼承下來.繼承的基本語法是: class 類名 extends 父類名{ //在寫自己需要的屬性和方法.} 討論繼承細(xì)節(jié): 討論繼承細(xì)節(jié): 1.父類的 public、protected 的屬性和方法被繼承.private 的屬性和方法沒有被繼承.2.一個(gè)類只能繼承一個(gè)父類,(直接繼承).如果你希望繼承多個(gè)類的屬性和方法,則使用多層繼承 class A{ public $n1=90;} class B extends A{ public $n2=“hello”;} class C extends B{ } $c=new C();echo $c->n1; 3.當(dāng)創(chuàng)建子類對象的時(shí)候,默認(rèn)情況下,不會(huì)自動(dòng)調(diào)用父類的構(gòu)造方法.class A{ public $n1=90; //構(gòu)造方法 public function __construct(){ echo “A __construct”; } } class B extends A{ function __construct(){ echo “B __construct”; } } //創(chuàng)建B對象實(shí)例 $b=new B(); 4.如果我們希望去調(diào)用父類的構(gòu)造方法,或者其它的方法(public / protected),可以這樣處理(了解) 4.1 類名::方法名()4.2 parent::方法名()舉例 class A{ public $n1=90; //構(gòu)造方法 public function __construct(){ echo “A __construct”; } } class B extends A{ function __construct(){ echo “B __construct”; //顯式的調(diào)用父類的方法 //A::__construct(); parent::__construct(); } } //創(chuàng)建B對象實(shí)例 $b=new B(); 5.當(dāng)一個(gè)子類的方法和父類的方法完全一樣(public protected), 我們稱為方法的覆蓋(方法重寫) 重載 基本概念: 函數(shù)名一樣,通過函數(shù)的參數(shù)個(gè)數(shù)或者是參數(shù)類型不同,達(dá)到調(diào)用同一個(gè)函數(shù)名,但是可以區(qū)分不同的函數(shù) class A{ public function test1(){ echo “test1”;} public function test1($a){ echo “test1 hello”;} } 重載 $a =new A();$a->test1();$a->test1(456);上面的這用用法是不對.PHP5 中如何通過魔術(shù)函數(shù)來實(shí)現(xiàn)方法重載的效果 代碼說明 class A{ public function test1($p){ echo “接收一個(gè)參數(shù)”; echo “ var_dump($p); } public function test2($p){ echo “接收兩個(gè)參數(shù) var_dump($p); } //這些提供一個(gè)__call //__call 是它一個(gè)對象調(diào)用某個(gè)方法,而該方法不存在,則 //系統(tǒng)會(huì)自動(dòng)調(diào)用__call function __call($method,$p){ var_dump($p); if($method==“test”){ if(count($p)==1){ $this->test1($p); }else if(count($p)==2){ $this->test2($p); } } } } $a=new A(); $a->test(1); $a->test(56,90); ?> 小結(jié): 關(guān)于重載 ① php5 默認(rèn)情況下不直接支持方法重載 ② php5 可以同__call魔術(shù)方法,模擬一個(gè)方法效果的效果 方法的重寫/方法的覆蓋(override)① 先看一個(gè)問題 當(dāng)一個(gè)父類知道所有的子類都有一個(gè)方法,但是父類不能確定該方法究竟如何寫,可以讓子類去覆蓋這個(gè)方法,具體用法如下: //抽象一個(gè)Animal類 class Animal{ public $name; protected $price; function cry(){ echo “不知道動(dòng)物怎么叫..”; } } class Dog extends Animal{ //覆蓋 function cry(){ echo “小狗汪汪叫..”; } } class Pig extends Animal{ //覆蓋.function cry(){ echo “哼哼叫..”; } } //創(chuàng)建一個(gè)只狗 $dog1=new Dog(); $dog1->cry(); $pig1=new Pig(); $pig1->cry();?> 關(guān)于方法重寫細(xì)節(jié)討論 1.要實(shí)現(xiàn)重寫,要求子類的那個(gè)方法的名字和參數(shù)列表個(gè)數(shù)一摸一樣,但是并不要求參數(shù)的名稱一樣.2.如果子類要去調(diào)用父類的某個(gè)方法(public / protected)則可以使用 parent::方法名(參數(shù)..), 父類名::方法名(參數(shù)...)3.在實(shí)現(xiàn)方法覆蓋的時(shí)候,訪問修飾符可以不一樣 //但是必須滿足: 子類的訪問范圍>=父類的訪問范圍 多態(tài)體現(xiàn)在什么地方? class Animal{ public function cry(){ echo '動(dòng)物叫喚..'; } } class Cat extends Animal{ public function cry(){ echo “abc”; } } $cat1=new Cat(); $cat1->cry();當(dāng)子類沒有覆蓋父類的方法則 $cat1->cry()調(diào)用的是父類,當(dāng)子類覆蓋了父類的方法,則調(diào)用自己的cry() 抽象類 為什么設(shè)計(jì)抽象類這個(gè)技術(shù)? 1.在實(shí)際開發(fā)中,我們可能有這樣一種類,是其它類的父類,但是它本身并不需要實(shí)例化,主要用途是用于讓子類來繼承,這樣可以到達(dá)代碼復(fù)用.同時(shí)利于項(xiàng)目設(shè)計(jì)者,設(shè)計(jì)類.快速入門 //在實(shí)現(xiàn)方法覆蓋的時(shí)候,訪問修飾符可以不一樣 //但是必須滿足: 子類的訪問范圍>=父類的訪問范圍 abstract class Animal{ public $name; protected $age; //這個(gè)方法沒有方法體,這個(gè)方法主要是為了讓子類去實(shí)現(xiàn).abstract public function cry(); } class Cat extends Animal{ public function cry(){ echo “貓貓叫喚..”; } } //創(chuàng)建一個(gè)子類實(shí)例 $cat1=new Cat(); $cat1->cry();使用抽象類的注意事項(xiàng): 1.基本用法 abstract class 類名{ //方法 //屬性 } 2.如果一個(gè)類使用abstract 來修飾,則該類就是抽象類, 如果一個(gè)方法被abstract修飾,則該方法就是抽象方法【抽象方法就不能有方法體.】 3.抽象類可以沒有抽象方法.同時(shí)還可以有實(shí)現(xiàn)了的方法. //在實(shí)現(xiàn)方法覆蓋的時(shí)候,訪問修飾符可以不一樣 //但是必須滿足: 子類的訪問范圍>=父類的訪問范圍 abstract class Animal{ public $name=“abc”; protected $age; //這個(gè)方法沒有方法體,這個(gè)方法主要是為了讓子類去實(shí)現(xiàn).abstract public function cry(); public function getName(){ return $this->name; } } class Cat extends Animal{ public function cry(){ echo “貓貓叫喚..”; } } //創(chuàng)建一個(gè)子類實(shí)例 $cat1=new Cat(); $cat1->cry(); echo $cat1->getName(); ?> 4.如果一個(gè)類中,只要有抽象方法,則該類必須聲明為abstract abstract class A{ abstract function test(); } echo “ok”; 5.如果A類繼承了一個(gè)抽象類 B,則要求A類實(shí)現(xiàn)從B類繼承的所有抽象方法 案例: //這是一個(gè)抽象類 abstract class A{ abstract function test(); } //B類要么自己抽象,或者實(shí)現(xiàn)從A類繼承的抽象方法.class B extends A{ function test(){ echo “我實(shí)現(xiàn)A:test()”; } } echo “hello” 接口 快速入門: //使用程序模擬現(xiàn)實(shí)情況 //定義規(guī)范(方法/屬性) interfaceiUsb{ public function start(); public function stop(); } //編寫相機(jī)類,讓它去實(shí)現(xiàn)接口 //1.當(dāng)一個(gè)類實(shí)現(xiàn)了某個(gè)接口,則要求該類必須實(shí)現(xiàn)這個(gè)接口的所有方法 class Camera implements iUsb{ public function start(){ echo “相機(jī)開始工作”; } public function stop(){ echo “相機(jī)停止工作...”; } } //編寫手機(jī)類 class Phone implements iUsb{ public function start(){ echo “手機(jī)開始工作”; } public function stop(){ echo “手機(jī)停止工作...”; } } //如何使用 $camera1=new Camera(); $camera1->start(); $camera1->stop(); echo “ //手機(jī)對象 $phone1=new Phone(); $phone1->start(); $phone1->stop();?> 1.接口的使用基本語法 interface 接口名{ //屬性 //方法 } 接口的方法都不能有方法體 如何去實(shí)現(xiàn)接口 class 類名 implements 接口名1,接口2.{ } 接口它的作用就是聲明一些方法,供其它類來實(shí)現(xiàn).接口還體現(xiàn)編程中我們希望的效果高內(nèi)聚低耦合的特點(diǎn): 繼承是實(shí)現(xiàn)接口的關(guān)系一覽圖 深入討論接口-interface 什么情況下可以考慮使用接口 1.定規(guī)范 2.定下規(guī)范,讓別的程序員來實(shí)現(xiàn),比如: //韓是項(xiàng)目經(jīng)理 //學(xué)生管理系統(tǒng)(students) //定義接口 interfaceStuManageInterface{ public function addStudent($stu); public function delStudent($id); public function updStudent($stu); } //給三 classStuManage { public function tianjiaxuesheng(){ } } //四 3.當(dāng)多個(gè)類,他們之間是平級(jí)的關(guān)系.這些類都會(huì)去實(shí)現(xiàn)某個(gè)功能,只是實(shí)現(xiàn)的方式不一樣.接口的細(xì)節(jié) 1.不能去實(shí)例化一個(gè)接口 interfaceiUsb{ } $a=new iUsb();(錯(cuò)誤!!) 2.接口中的所有方法,都不能有方法體 3.一個(gè)類可以去實(shí)現(xiàn)多個(gè)接口 語法: class 類名 implements 接口1,接口2{ } 4.接口中可以有屬性,但是必須是常量,并且是public interfaceiUsb{ const A=90; } echo “ok”.iUsb::A; 5.接口的方法是public 【默認(rèn)就是public 】 ,不能是 protected 和private 舉例: interfaceiUsb{ const A=90; function test(); } echo “ok”.iUsb::A;6.類和接口之間關(guān)系一覽圖 代碼: interface iUsb2{ public function a(); } interface iUsb3{ public function b(); } interfaceiUsb extends iUsb2,iUsb3{ const A=90; function test(); } class Class1 implements iUsb{ public function a(){ } public function b(){ } public function test(){ } } echo “ok”.iUsb::A;?> 從上面我們看出 ① 一個(gè)接口可以繼承多個(gè)其它的接口.當(dāng)一個(gè)類去實(shí)現(xiàn)了某些接口,則必須把所有接口的方法,都實(shí)現(xiàn) 繼承和實(shí)現(xiàn)接口的比較:(1)可以認(rèn)為實(shí)現(xiàn)接口是對單一繼承的補(bǔ)充.(2)可以在不破壞類層級(jí)關(guān)系的前提下,對某個(gè)類功能擴(kuò)展.final關(guān)鍵字 1.如果我們希望某個(gè)類不被其它的類來繼承(可能因?yàn)榘踩紤]...), 可以使用final final class A{ } class B extends A{ } echo “ok”;?> 2.如果我們希望某個(gè)方法,比如計(jì)算個(gè)人所得稅的方法,不能子類改寫,可以使用fianl來修飾方法 class A{ final public function getRate($salary){ return $salary*0.08; } } class B extends A{ //不能去覆蓋父類的getRate方法./*public function getRate($sal){ return $sal*0.01; }*/ } $b=new B(); echo $b->getRate(100);3.final關(guān)鍵字不能去修飾屬性.const關(guān)鍵字的講解 //當(dāng)你有一個(gè)屬性,不希望被修改,則考慮使用const做成常量 基本用法是 class A{ const常量名=賦初值;} interface 接口名{ const常量名=賦初值;} 常量是public 使用類名::常量名;接口名::常量 class A{ //常量在定義的時(shí)候,必須給初值.//const關(guān)鍵字前面不要帶修飾符號(hào).const TAX_RATE=0.08; public function payTax($val){ //常量不能修改.//A::TAX_RATE=0.01; //return $val*self::TAX_RATE;【ok】 return $val*A::TAX_RATE;//【ok】 } } $a=new A(); echo $a->payTax(200);?> 1.常量在定義的時(shí)候需要賦初值 2.常量不能修改.3.常量名不能有 $, 一般是大寫, 默認(rèn)是public 4.常量在類的內(nèi)部使用 self::常量的名稱類名::常量的名稱 在類的外部使用類名::常量的名稱.面向?qū)ο缶幊痰木C合案例 現(xiàn)在我們一起來完成一個(gè)稍微綜合的案例---php版本的計(jì)算器,從而加深對php的認(rèn)識(shí),為下一步學(xué)習(xí)做準(zhǔn)備。先用兩個(gè)頁面來完該計(jì)算器: myCal.php(界面)myResult.php(計(jì)算)知識(shí)點(diǎn): 1.如何接收php頁面提交的數(shù)據(jù),并處理 2.php中如何使用javascript完成對數(shù)據(jù)合法性的校驗(yàn) 我們一起來開發(fā).5.畫出程序框架圖: 6.編寫代碼: 現(xiàn)在我們分析如果要求把 xml 的作業(yè)改成面向?qū)ο蟮姆绞?怎么該? 做網(wǎng)站 Web程序。 需要制作一臺(tái)可以在網(wǎng)絡(luò)上被別人訪問到的機(jī)器。 安裝了瀏覽器的計(jì)算機(jī): browser端 能夠提供網(wǎng)絡(luò)資源的計(jì)算機(jī):(網(wǎng)站在這臺(tái)計(jì)算機(jī)上),能夠提供某種服務(wù)。Server端。 B/S是什么意思? 瀏覽器/服務(wù)器的架構(gòu): 請求:瀏覽器端向服務(wù)器端發(fā)送數(shù)據(jù)。Request 響應(yīng):服務(wù)器向?yàn)g覽器端發(fā)送數(shù)據(jù)。回應(yīng),Response 什么樣的計(jì)算機(jī)叫做服務(wù)器端? 安裝了服務(wù)器軟件的計(jì)算機(jī)。 Web服務(wù)器軟件:iis,nginx,apache。 其中apache還是目前與php配合使用最多的服務(wù)器軟件: 安裝apache這個(gè)軟件,使jsj成為一臺(tái)web服務(wù)器。 http:// Apache的默認(rèn)的文檔目錄 apache的安裝目錄下/htdocs/ 什么是靜態(tài)網(wǎng)站,動(dòng)態(tài)網(wǎng)站? 靜態(tài),網(wǎng)站上所有的內(nèi)容,都是由靜態(tài)頁面提供的。 動(dòng)態(tài):網(wǎng)站的內(nèi)容,是來源于某個(gè)數(shù)據(jù)源(數(shù)據(jù)庫,互聯(lián)網(wǎng)),而,在需要展示某些數(shù)據(jù)時(shí),通過某種語言,將數(shù)據(jù)從數(shù)據(jù)源內(nèi)提取,然后再展示到頁面上。 如果需要做動(dòng)態(tài)網(wǎng)站,需要 1,數(shù)據(jù)源(數(shù)據(jù)庫)mysql數(shù)據(jù)庫 2,某種語言(用于提取和展示數(shù)據(jù)之用)PHP Amp開發(fā): 利用apache作為web服務(wù)器,使別人可以訪問到我們的網(wǎng)站 利用mysql作為數(shù)據(jù)源,可以保存動(dòng)態(tài)網(wǎng)站所需要的數(shù)據(jù) 利用php來獲得某個(gè)操作所需要的數(shù)據(jù)。 小測試: 輸出1-100 編寫php文件: 訪問這個(gè)php文件: 發(fā)現(xiàn),可以訪問到,但是不能解析。 Apache只有提供被訪問的功能,而不能提供解析php代碼的功能。 因此需要安裝php程序,提供解析php代碼的功能: 安裝PHP: 所有的請求都是web服務(wù)器來接收的(apache),但是其中某些資源需要php來處理。通常的處理方式,是將php作為apache內(nèi)部的一個(gè)模塊來管理的。 將php安裝成apache模塊: 使用一個(gè)apache的指令,loadModule來完成: 解壓php的安裝包: 不需要安裝可以直接執(zhí)行 將php軟件復(fù)制到相應(yīng)的目錄: E:/amp/php 由于不需要安裝,目錄內(nèi)的可執(zhí)行文件直接可以使用: 在php目錄內(nèi),有個(gè)文件,就是php為apache提供的apache模塊: 需要使用apache的LoadModule載入這個(gè)模塊即可: 需要在apache的配置文件內(nèi),使用上面的LoadModule指令: apache的配置文件在 apache的安裝目錄/Conf/httpd.conf 增加如下指令即可: 修改配置文件后,需要重啟動(dòng)apache服務(wù)才可以: 配置apache,告知apache,哪樣的前請求需要調(diào)用php來解析,而哪些不需要: 通過請求的資源的后綴名 使用apache的FilesMatch指令來完成: 當(dāng)匹配到php后綴時(shí),調(diào)用php來處理: Apache的配置文件內(nèi): 請求php文件時(shí),php代碼可以執(zhí)行: 大家可以使用phpinfo()函數(shù)來測試以下,當(dāng)前的php運(yùn)行的環(huán)境: 安裝php后,需要配置一些最基本的配置項(xiàng): 修改php的配置文件: Php的安裝目錄/php.ini 根據(jù)需要,將相應(yīng)的更改成php.ini即可: 由于php作為apache一個(gè)模塊,因此需要告知apache,在哪里才能找到php的配置文件。利用apache的指令PhpIniDir來完成: 修改配置文件,達(dá)到某些目的: 1,時(shí)區(qū) 2, php擴(kuò)展文件的目錄。Php的很多功能,并不是內(nèi)置到php的軟件內(nèi)的。在需要使用某個(gè)功能時(shí),再載入即可。這個(gè)擴(kuò)展的功能文件是被保存到某個(gè)目錄內(nèi)的,稱之為php的擴(kuò)展目錄: Extension_dir: 修改完了php的配置,也需要重啟apache才能生效 如果我們的php需要操作數(shù)據(jù)的話,需要利用數(shù)據(jù)軟件了。安裝Mysql。 1,安裝 2,配置 配置mysql的安裝目錄,和mysql數(shù)據(jù)的保存目錄: 安裝完成時(shí),勾選運(yùn)行配置向?qū)?,完成配置的過程: 配置字符集: 簡單介紹Mysql: 數(shù)據(jù)庫服務(wù)器: 屬于server端。因此,需要等待某個(gè)程序請求他才可以運(yùn)行。 能夠?qū)ysql數(shù)據(jù)庫服務(wù)器發(fā)出請求的我們稱之為mysql客戶端。 C/S Client客戶端 Server服務(wù)器 在安裝完mysql后,其實(shí)安裝了2個(gè)軟件1,mysql的服務(wù)器端,2,mysql的客戶端。 我們需要使用php來操作mysql。 其實(shí) 在php操作mysql的過程中,php就變成了 mysql的客戶端。 Php能夠作為mysql的客戶端,使用php的php_mysql.dll這個(gè)擴(kuò)展完成,而且,這個(gè)擴(kuò)展不是默認(rèn)開啟的。 開啟相應(yīng)的mysql的操作擴(kuò)展,利用php的指令extension來完成。Php.ini: B/S C/S 1,服務(wù)器在監(jiān)聽(運(yùn)行),提供某個(gè)服務(wù) 2,瀏覽器或者客戶端,對服務(wù)器發(fā)出請求。在發(fā)送請求時(shí),請求的數(shù)據(jù)一定要按照某種數(shù)據(jù)格式才可以。數(shù)據(jù)格式在網(wǎng)絡(luò)數(shù)據(jù)傳輸時(shí)稱之為網(wǎng)絡(luò)協(xié)議。3,服務(wù)器接收到請求后,會(huì)根據(jù)請求數(shù)據(jù),進(jìn)行相應(yīng)的操作。4,將處理好的結(jié)果返回給瀏覽器(客戶端),回應(yīng)。Response 5,瀏覽器端(客戶端)對回應(yīng)的數(shù)據(jù)進(jìn)行展示輸出,b/s 都是用瀏覽器發(fā)出請求的。 http https c/s架構(gòu),都是采用某個(gè)服務(wù)專用的客戶端發(fā)出的請求。 Bs架構(gòu)通常,任何兩次請求回應(yīng)周期是沒有任何聯(lián)系的。在發(fā)出請求時(shí),都需要先建連接。 Cs通常,在連接一次之后,通常就會(huì)保持住這個(gè)連接,后續(xù)的操作,就不需要再次建立連接了。 PHP與apache聯(lián)系: 1,php作為apache的模塊而存在。loadModule 2,web服務(wù)器與php之間通過 CGI方式產(chǎn)生聯(lián)系。CGI(通用網(wǎng)關(guān)接口),IIS+PHP?,F(xiàn)在CGI被fastCGI。Nginx+PHP apache的虛擬主機(jī): 通常一個(gè)web服務(wù)器,代理的是一個(gè)網(wǎng)站。 有時(shí)我們需要利用一個(gè)web服務(wù)器,管理多個(gè)站點(diǎn)。不同的站點(diǎn)擁有獨(dú)立的域名。 通過配置apache服務(wù)器,達(dá)到,訪問 Test.kang.com時(shí),看到的是test目錄的內(nèi)容。Shop.kang.com時(shí),看到的是shop目錄的內(nèi)容 Apache的基于域名的虛擬主機(jī)技術(shù): 主機(jī):一個(gè)網(wǎng)站,就是一些php文件的集合,一個(gè)保存php文件的目錄 域名:指向某個(gè)網(wǎng)站的名稱。 通過修改apache配置文件達(dá)到效果: Apache/comf/httpd.conf 原則上在這個(gè)配置文件內(nèi)寫虛擬主機(jī)的配置就可以了。但是通常我們都是將虛擬主機(jī)的配置寫到某個(gè)單獨(dú)的配置文件內(nèi),然后將這個(gè)虛擬主機(jī)配置文件再載入到apache的這個(gè)httpd.conf配置文件內(nèi)。引入的操作: 虛擬主機(jī)的專門的配置文件: 編輯這個(gè)虛擬主機(jī)文件,增加虛擬主機(jī): 在配置文件內(nèi),每一個(gè) 域名和目錄是一個(gè)虛擬虛擬主機(jī)最基本的必備元素。 完成以上的操作,apache配置已經(jīng)完成,apache上已經(jīng)存在兩個(gè)虛擬主機(jī)了: 在配置了虛擬主機(jī)之后,我們對web服務(wù)器的默認(rèn)訪問(沒有使用配置的虛擬主機(jī)域名的訪問),都會(huì)訪問到默認(rèn)的主機(jī)上。 默認(rèn)的主機(jī): 1,在配置了虛擬主機(jī)后:默認(rèn)的主機(jī)就是 第一個(gè)配置的虛擬主機(jī) 2,在沒有配置虛擬主機(jī)時(shí),是htdocs目錄。 那么怎么才能在使用虛擬主機(jī)的前提下,讓localhost訪問到原來的htdocs? 如何能夠通過在瀏覽器上輸入相應(yīng)的虛擬主機(jī)域名訪問到我們的虛擬主機(jī)呢? 在瀏覽器端,需要通過相應(yīng)的域名,解析成目標(biāo)服務(wù)器的ip地址才可以。 可以通過過瀏覽器端操作系統(tǒng)上自帶的 域名解析文件完成。Hosts 配置虛擬主機(jī)時(shí),常用的配置: 目錄的權(quán)限的配置 利用apache的directory指令段完成配置 看 httpd.conf的配置: 目錄級(jí)別的配置,對當(dāng)前目錄,及其后代目錄有效果。 如果在apache的配置文件內(nèi),沒有對某個(gè)目錄進(jìn)行配置,則采用默認(rèn)的目錄配置 可以通過修改默認(rèn)的配置達(dá)到目的,但是通常是針對目錄進(jìn)行單獨(dú)配置: 增加一個(gè) Directory指令段: 為了將目錄與虛擬主機(jī)聯(lián)系起來,通常在VirtualHost內(nèi),使用Directory指令 Conf/extra/httpd-vhosts.conf 直接訪問目錄的配置: 在訪問目錄時(shí),先檢測當(dāng)前目錄是否配置了目錄索引頁,如果配置了索引頁,則展示索引頁的內(nèi)容。目錄的索引頁使用apache的指令 directoryIndex完成配置。這個(gè)指令是可以寫到directory段內(nèi)。 如果沒有配置目錄索引頁:則需要將目錄的的內(nèi)容以列表的形式顯示出來,但是是通過配置apache的指令options加以配置,是否可以顯示目錄的索引列表。 可以在配置 options時(shí) 增加上允許符號(hào)連接的配置: Apache的配置文件系統(tǒng): Apache程序,只會(huì)在apache服務(wù)器啟動(dòng)時(shí),讀取apache配置文件的內(nèi)容,稱之為apache主配置文件。 一旦配置文件的語法出錯(cuò),就會(huì)導(dǎo)致apache服務(wù)器啟動(dòng)失敗,提示: Apache提供一個(gè)apache的配置文件檢查的功能: 也可以通過 cmd,命令行運(yùn)行: Apache還有一個(gè)配置文件,稱之為apache的分布式配置文件,apache允許在某個(gè)目錄內(nèi)部,使用獨(dú)立的配置文件,來配置當(dāng)前目錄及其后代目錄的中的一些設(shè)置。但是此時(shí)配置文件名稱,就不是httpd.conf了 而是.htaccess 在這個(gè).htaccess配置文件中配置的內(nèi)容,只能是目錄級(jí)別的配置。 但是默認(rèn)情況下,分布式配置文件是不可以使用的。可以通過在主配置文件中使用apache的 Allowoverride指令加以配置。由于分布式配置文件是配置目錄的,因此 allowoverride也是需要寫到Directory段。 分布式與主配置文件的區(qū)別: 1,主配置文件需要保存到Conf目錄中,而分布式需要保存到所有需要配置的目錄中 2,主配置文件只要在apache啟動(dòng)時(shí),才讀取,而分布式配置文件,在apache訪問到某個(gè)目錄時(shí)都會(huì)讀取一次。 作業(yè) 1,每個(gè)人配置一個(gè)虛擬主機(jī): 域名是 test.ip.com Test.100.com 2,在test.ip.com上增加一個(gè)表單頁面 Welcome.html頁面 最好在表單提交時(shí),驗(yàn)證姓名不能為空,為空給出提示,不能提交。 分析上面的例子: 發(fā)生了幾次請求和回應(yīng)的過程。
”;
有”.$global_nums;?>
有這”.Child::$nums;
接收到參數(shù)是”;
”;
”;第二篇:傳智播客 PHP程序員筆記第一天