1. 程式人生 > >PHP面向物件(OOP)

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 類名稱();

記憶體從邏輯上分為四段

棧空間段,堆空間段,程式碼段,初始化靜態段

類是具有相同屬性和服務的一組物件的集合。

類和物件的關係

類與物件的關係就如磨具和鑄件的關係。物件是類的例項化,類是物件的抽象。