PHP面向物件(OOP)
自動載入類
__autoload(){}
會在使用尚未被定義的類的時候自動呼叫此函式,autoload函式接收一個引數,即需要引入的類名。
function __autoload($className){
require_once $className.".php";
}
$obj=new MyClass(); //MyClass類不存在自動呼叫函式__autoload(),在例項化類的時候寫__autoload()函式。此例項化時會傳入引數“MyClass”。
此時不必將所需引入的類都一一 include進來。
物件序列化
序列化:serialize(); 當某些物件需要在網路上傳輸,為了傳輸方便,可以將物件轉為二進位制串,當到達另一端時,再還原為原來的物件。
反序列化:unserialize(); 把物件的二進位制串再轉為物件。
$p1=new Person('張三','男','20');
$p1_string=serialize($p1);
echo $p1_strubg;
$p2=unserialize($p1_string);
魔術方法:
__sleep():在序列化之前做一些操作(該方法不接受引數,但返回一個數組)
__wakeup():由二進位制串重新組成新物件時,做一些物件醒來做的事。
function __sleep(){ $arr=new array('name','sex'); //數組裡是需要進行序列化的屬性名 return $arr; } function __wakeup(){ $this->age='36'; }
多型
子類繼承父類,重寫父類的方法,方法名相同,引數型別和引數個數不同,實現不同的效果。
介面interface
接口裡的方法都是抽象方法,可以省略abstract關鍵字,預設都是抽象方法。
接口裡不能宣告變數,只能宣告常量(const )。
接口裡所有的成員都是public許可權的,也可省略不寫,預設public。
介面是特殊的抽象類,裡面所有的方法都是抽象方法,不能產生例項化物件,所有抽象方法需要子類去實現。
子類實現介面中的抽象方法用implements,介面繼承介面使用extends
抽象方法
使用abstract關鍵字修飾,沒有方法體,abstract function fun1();
抽象類
只要類裡有一個方法是抽象方法,這個類就要定義為抽象類,使用abstract關鍵字。
抽象類不能被例項化。
子類繼承父類,子類必須實現父類全部的抽象方法,否則等於子類中包含抽象方法,子類也不能被例項化。
__call 處理呼叫錯誤
當呼叫的方法名錯誤或不存在呼叫的方法時,將執行該函式。
第一個引數:呼叫錯誤的方法名;
第二個引數:呼叫錯誤的方法時傳的引數,以陣列的形式傳過來。
class Person{
function __call($errFunName,$arrs){
print('您呼叫的方法:'.$errFunName."(引數為:");
print_r($arrs);
print(')錯誤或不存在!');
}
}
$p1=new Person();
$p1->run('1min','500m');
echo "Hello"; //當不存在__call方法時,如果呼叫不存在的方法,不會執行到此句。
克隆物件 clone
根據一個物件克隆出另一個一樣的物件,克隆後兩個物件互不干擾。
$p1=new Person('李木子','20','女');
$p2=clone $p1;
//使用clone克隆新物件p2,和p1物件具有相同的屬性和方法。
在物件克隆時會自動呼叫"__clone"方法,該方法可以建立一個與原物件擁有相同屬性和方法的物件。若想在克隆後改變原物件的內容,可以重寫此方法。
"__clone"方法包含兩個指標:$this指向複本,$that指向原本。
class Person{
...
function say(){
echo "我叫:".$this->name.",今年".$this->age."歲";
}
function __clone(){
$this->name="我是假的".$that->name;
$this->age='100';
}
}
$p1=new Person('張三','20','男');
$p2=clone $p1;
$p1->say();
$p2->say();
__toString() 輸出物件引用時自動呼叫
$p1=new Person(); 此時$p1就是一個引用,此時如果輸出“echo $p1;”會出錯。
function __toString(){
echo "您輸出的是個引用";
}
static
靜態成員屬於類,在類第一次被載入的時候分配的空間,其他類無法訪問,只對類的例項共享。
從記憶體角度:物件是在堆記憶體中,物件的引用放在棧記憶體中。靜態成員放在“初始化靜態段”,在類第一次被載入的時候放入的,可以讓堆記憶體裡面的每個物件所共享。
訪問靜態方法:類名::方法名();
訪問靜態屬性:類名::$屬性名;
類裡的靜態方法只能訪問靜態屬性(想在本類的方法中想訪問本類的其他成員,需要使用$this這個引用,而靜態方法不用物件呼叫的,而是使用類名來訪問的 ,所以沒有物件的存在,也就沒有$this這個引用)
非靜態方法可以訪問靜態屬性,通過“self::成員屬性名”
const定義常量
也可使用define()函式
訪問常量時通過類名,在方法裡通過self,但是不使用$符號,也不能使用物件來訪問。
訪問:
類名::常量名(不加$符號)
self::常量名(不加$符號)
final關鍵字
使用final關鍵字標記的類不能被繼承。
使用final關鍵字標記的方法不能被子類覆蓋。
三種訪問修飾符
public(公有的,預設的),private(私有的),protected(受保護的)
private | protected | public | |
同一個類中 | ok | ok | ok |
類的子類中 | ok | ok | |
所有的外部成員 | ok |
方法過載
方法名相同,引數個數和引數型別不同
方法覆蓋
子類繼承父類,通過重寫父類相同的方法名實現覆蓋,重寫父類的方法
想在父類方法的基礎上進行擴充套件:
呼叫父類被覆蓋的方法:
parent::方法名();
類名::方法名();
class children extends Person{
...
function say(){
//Person::say();
parent::say();
echo "在這可以加點功能";
}
}
繼承
已存在的用來派生新類的類成為基類,又稱為父類以及超類;由已存在的類派生出的新類稱為派生類,又稱子類。
通過繼承,可以得到父類的方法和屬性,也可以擴充自己,新增新的屬性和方法。“可重用行”。
__set()
用來為私有成員屬性設定值。有兩個引數,第一個引數為設定的屬性名,第二個引數為設定的屬性值。
function __set($property_name,$value){
$this->$proprty_name=$value;
}
__get()
用來獲取私有成員屬性的值。
function __get($property_name){
if(isset($property_name)){
return $property_name;
}else{
return NULL;
}
}
isset()
傳入一個變數作為引數,如果存在返回true,不存在返回false。
unset()
傳入一個變數,刪除指定的變數。
封裝性
使用private對屬性和方法進行封裝。封裝的成員不能被類外面之間訪問,只有物件內部可以訪問。
建構函式__construct()
使用new關鍵字來例項化物件的時候會自動呼叫構造方法,可以做一些初始化的工作,如為成員屬性賦初值。
解構函式__destruct()
在銷燬一個類之前執行一些操作。
$this
本物件的引用
$this->屬性
$this->方法
使用物件的成員
物件成員包括成員屬性和成員方法。通過“->”操作符訪問
物件->屬性
物件->方法
例項化物件
$物件名稱 = new 類名稱();
記憶體從邏輯上分為四段
棧空間段,堆空間段,程式碼段,初始化靜態段
類
類是具有相同屬性和服務的一組物件的集合。
類和物件的關係
類與物件的關係就如磨具和鑄件的關係。物件是類的例項化,類是物件的抽象。