1.復習OOP:
* 析構函數:|--默認是在程序結束時自動調用,目的是釋放所有的資源{比如打印機資源}
|--本質:PHP通過監測一個對象或者變量,發現它再不會被使用,就決定銷毀它,釋放內存。
* 但是注意 *
檢測一個對象是不是真的再也不會被調用,除了默認在程序結束的那一刻之外,我們是可以人為干預的:
比如,我們提前銷毀一個變量$a,系統就會調用析構函數{目的是釋放$a占據的內存}
我們提前把一個對象$obj=null,它也會認為再不用這個對象了,也會調用析構函數釋放$obj的內存
但是注意:這里設計一個對象引用的東西:
$obj1 = $obj
//這里相當於創建了$obj的引用,當$obj=null, $obj1依舊指向這個對象,無影響,所以這個候 即使你銷毀了$obj, 而$obj1依舊在占據着這個對象的資源,在后台運行。
{析構函數不會被調用}
$obj2 = &$obj
//這也是一個對象引用,區別上面的特點是:$obj2和$obj可以認為是一個變量的兩個名字,一 概全改,一銷毀全銷毀。他們其實就是一個東西。
如果$obj = null或者被銷毀,$obj2也不復存在。
{析構函數會被調用}
*繼承符號: extends //繼承的局限性:
*訪問控制:public
private //僅自身類的內部
protected //自身類和子類的內部
//字段被封裝了不能在類外部直接訪問,可以,在類內部,立馬寫一個public方法,
外部通過訪問這個public方法來訪問它。
* static屬性和方法:
|--定義方法:public static fuction add(){};
public static $hello ;
|--靜態屬性保存所有對象共有的屬性,
靜態方法只能訪問靜態屬性,{當然public可以訪問所有的類型變量。}
靜態成員直接用類調用,不可以實例化對象。
|--特點及訪問方式:靜態方法和字段創建的目的就是為所有對象服務{也可以說不是為某個特定對象服務}
所以它的訪問方式是
類外部: NbaPlayer::add {直接用類名調用,不允許用對象調用}
NbaPlayer::$hello {$符號注意帶上}
類內部: self::add();
self::$hello;
static::add();
static::$hello();
|--但是現在:如果父類里有一個static變量或方法,子類默認是....
那么怎么訪問他呢?
如:父類man里static變量: haoge,
在子類big_man類內部只需要這么調用: parent::$haoge;就OK了,等於把self改成parent
但是之類外部就不能訪問了。
* 重寫:子類中定義一個和父類方法名相同的方法{只要求方法名相同},這就是重寫。
調用方法時,按子類的規則來。
//重載:PHP中雖然沒有如同java子類語言那種“允許一個類定義里面用一個函數名寫多個方法{每個方法參數不同或 函數返回值類型不同}”
這種機制實現重載,但是由於PHP不講究變量類型,所以它也想出了一套方案:
在這個方法定義的時候一次性寫全所有的參數,並且給定默認值,之后當我們需要調用的時候,傳入不同的
參數,就產生不同的結果,等於是重載了。
*注意:*重載是“一個類定義方法的時候方法的多態性”,而重寫發生在“子類繼承父類對一個方法的多態性”
*final關鍵字:
父類的定義的前面加一個final那么任何類都不能繼承這個父類。
如果父類的一個方法A定義時前面加了個final,那么任何繼承父類的子類都不允許重寫這個方法A。
* 關鍵字訪問: |-- parent關鍵字
我們有了重寫之后,默認在“子類定義時”訪問方法A已經是被重寫之后的方法了:$this->A();
這個時候,如果還想訪問父類的原來的方法A,只要使用parent就OK了: parent::A;
//當然,在開始說static的時候,parent也是神器。
|-- self關鍵字
在任何類的定義時: $this->hello() <=> self::hello(); //訪問方法
const PI = 3.14; $this->PI <=> self::PI ; //訪問常量
static //當然可以訪問靜態變量。
//但是self比較奇葩的是,它不支持類自身屬性{變量}的訪問,
所以除了要調用static,還不如全部用$this->...方便清晰。
|-- static關鍵字
只用於訪問類自身定義時,定義的static的屬性,方法。
* 接口:
|--意義:
|-- 解決了PHP只能單繼承帶來的缺陷,現在也可以大量繼承很多方法了。
|-- 怎么個復用性看具體項目吧.
|--利於分工合作開發:
A負責接口的方法在某些類中的的具體實現,
B直接調用接口的方法做項目的其他步奏,無須管他怎么實現
|-- 用法:
|-- //interface關鍵字定義接口。注意接口命名是駝峰法。
interface IcanEat {
public function eat($food); //接口里面只寫方法聲明,不許實現。
}
//implements關鍵字實現接口
class haoge implements IcanEat {
public function eat($food){ //在實現了接口的類里,必須把方法具體實現出來。
echo "haoge eat {$food}";
}
}
//接口不能被實例化
//可以用instanceof關鍵字來查看對象是否實現了某個接口:
var_dump($obj instanceof IcanEat ); //若bool true 則說明obj這個對象實現了接口
{這個instanceof作用在於:有時候需要判斷某個方法是否能被某個對象調用,做一下安全檢查}
//可以用extends實現子接口繼承父接口:
interface IcanRun extends Icaneat{
public function run($distance);
}
//當一個類實現了這個子接口時,不但要實現子接口的方法,還要實現子接口對應的父接口....
class haoge implements IcanRun{
public function eat($food){.......};
public function run($distance){........};
}
* 多態:
這里的PHP多態就是一個接口但是被不同類做了不同的實現,所以不同對象調用同一方法產生不同效果,即多態。
* 抽象類:
|--特點:abstract類的結構介於類和接口之間,就是既包括需要具體實現的普通方法,
也包括抽象方法{不許實現}
|-- abstract public class AcanEat{
public function breath{ //普通方法,需要具體實現。
echo "we are all need breah";
}
abstract public function eat($food); //abstract標示,不需要實現,也不能實現
}
class human extends AcanEat{
abstract public function eat($food){ //繼承了抽象類,只需要具體實現抽象方法即可。
echo "haoge like {$food}";
}
}
*PHP的特殊OOP性質*:
|--魔術方法:
* __tostring() :當對象被當做一個string時,該方法自動調用
* __invoke(): 當對象被當做一個方法時,...
實例:{可做個試驗玩哇}
class MagicTest{
public function __tostring(){
return "this is a magic method";
}
public function __invoke($x){
echo "__invoke called with {$x}";
}
}
$obj = new MagicTest;
echo $obj ; //對象被當做一個string使用了,所以調用__tostring。
$obj(5); //對象被當做一個方法使用了,所以調用了__invoke。
* __call() :
* __callStatic() :
案例:
class MagicTest{
//相當於重載了一次haoge();
public function __call($name, $arguments){
/* 這里$name就是待會兒訪問不存在的方法名haoge,
$arguments就是傳入haoge的參數形成的數組,
他們由系統自動捕獲,我們不用管它。
*/
echo "calling with {$name} with parameter ".implode(",", $arguments);
} //implode是分割函數
//這里相當於重載了static的haoge();
public static function __invoke($x){
echo "static calling with {$name} with parameter ".
implode(",", $arguments);
}
}
$obj = new MagicTest;
$obj->haoge("haha", "hehe"); //訪問不存在的haoge(),so...
MagicTest::haoge("haha", "hehe") //訪問不存在的static的haoge(),so....
//這個魔術方法真的很神奇,一個不存在的方法被調用后,出現了兩種結果。
* __get() : 在讀取"不可訪問"的屬性時...
* __set() : 在給"不可訪問"的屬性賦值時...
* __isset() : 在對"不可訪問"的屬性使用isset()時...
* __unset() : 在對"不可訪問"的屬性使用unset()時...
//不可訪問的屬性:比如private,protected,未定義的變量...
案例:{這四個家伙也被稱為屬性的重載}
class MagicTest{
public function __get($name){ //這里的$name是系統捕獲的屬性名
return "the undifined property is {$name} ";
}
public function __set($name, $value){
return "the property: {$name} has value: {$value}";
}
private $priva;
public function __isset(){
echo "__isset is called";
}
public function __unset(){
echo "__unset is called";
}
}
$obj = new MagicTest;
$obj->hello; //獲取一個不存在的屬性,so...
$obj->hello = 1000; //給一個不存在的屬性賦值,so...
isset($obj->priva); //判斷一個private的變量非空否,so...
unset($obj->hello); //刪除一個不存在的hello變量,so...
* __clone :
首先聲明,當使用clone關鍵字復制對象時,只要用戶定義了__clone,就會自動調用__clone
class MagicTest{
public $name;
}
$test1 = new MagicTest;
$test1->name = "haoge";
$test2 = clone $test1; //復制一個完全相同的test1,連屬性值都相同。
var_dump($test2->name);
如果你想在clone的時候,給clone的新對象test2做點操作,比如修改它的$name,
就需要定義__clone了。
class MagicTest{
public $name;
public function __clone(){
$this->name = "hhq";
}
}
$test1 = new MagicTest;
$test1->name = "haoge";
$test2 = clone $test1;
var_dump($test2->name); //test2已經發生變化。
var_dump($test1->name); //我們發現test2的改變不會引起test1的任何改變。
clone 和對象引用是不一樣的,具體區別:
http://www.zhihu.com/question/28363811
http://www.cnblogs.com/gameboy90/archive/2011/11/02/2232682.html
http://weizhifeng.net/php-clone.html
{明天花時間一定立刻要弄清楚!!!很重要!!!}
2.接口基礎:
|--APP接口:
|--APP如何通信:
|--通信數據格式區別:
|--接口做了什么:
|--json 封裝接口數據:
|--xml封裝接口數據:
|--PHP生成xml文件:
|--直接輸出:
|--dom類的方法:待谷歌之。
|--封裝實例:
* 方法
* data數據類型分析:
|--array('name'=> 'haoge', 'love'=> 'hhq'); //key為字母,結構正常
|--array(1, 2, yunda); //key為數字,xml解析節點不允許是數字
|--array('name'=> 'hhq', yunnan); //key既有正常的,也有數字,這是混編
|--array('name'=> 'haoge', array(1, 2, 'haoge')); //,key為數字,value有的是數組
value為數組它也能通過遞歸處理
關鍵是key是數字怎么辦?
<0>haoge</0> ==> <item id="0"><item> 這樣就轉化過去了{以屬性來賦值}
接下來全是代碼。具體敘述要見代碼和注釋。