object oriented
)世間萬物皆對象,抽象的也是對象,一切可見或不可見都是對象php
對象包含兩個部分:編程
對象的組成元素segmentfault
數據模型
,用於描述對象的數據屬性
,或者對象的成員變量
對象的行爲數組
行爲模型
,用於描述對象可以作什麼事情方法
屬性
和方法
組織起來方法
的調用完成互動
高內聚
特定的職能
(職能可大可小)低耦合
軟件設計儘量的作到:高內聚,低耦合,模塊與模塊間應該是獨立的,沒有依賴關係數據結構
實例
(Instance)類成員
class
開始,後面跟着這個類的名稱。類的命名一般每一個單詞的第一個字母大寫,以中括號開始和結束new
,new
以後緊跟類的名稱和一對括號->
符號來訪問$this
是Php
裏面的僞變量
,表示對象自己。能夠經過$this->
的方式訪問對象的屬性和方法new
實例化對象的時候,都會用類名後面的參數列表調用構造函數php
類函數的構造函數function __construct(){}
運行時自動調用function __destruct(){}
析構函數是根據後入先出的原則null
或者程序結束時會被自動調用析構函數,,所佔用的資源被系統回收若是被複制了,而不是
&引用,就不會調用析構函數
&
引用的基本概念$james1 = $james; //至關於複製出來多一個引用,二者是獨立的兩個引用 $james2 = &$james; //至關於爲james取一個別名,二者實際上是一體的,只是有兩個名字
特別注意:函數
PHP 永遠會將對象按引用傳遞
(ArrayObject
是一個SPL
對象
,它徹底模仿數組的用法,可是倒是以對象來工做)$arr = array(); $arr2 = $arr;
$arr2
是$arr
數組的一份拷貝
,它們之間互不影響,是獨立的兩個數組&
對象(數組)都是至關於起別名
父類:擁有部分相同的屬性和方法this
繼承的好處spa
子類能夠修改和調用父類定義的類成員設計
重寫
(Overwrite
)子類:3d
$this
訪問父類的屬性PHP
的單繼承特性
:類不容許同時繼承多個父類(extends
後面只能跟一個父類名稱)面向對象的三種訪問權限:
public
是公有的類成員,能夠在任何地方被訪問
protected
受保護的類成員,能夠被其自身以及繼承的子類訪問
private
私有的類成員,只能被自身訪問
靜態成員:定義時在訪問控制關鍵字後添加static
關鍵字便可(訪問控制關鍵字:public. protected. private
)
self::
或 static::
關鍵字訪問自身靜態成員,self::$
屬性 self::方法() parent::
關鍵字訪問父類的靜態成員,也能夠經過子類::父類靜態成員類名::
的方式在類的外部訪問靜態成員class
以前添加final
關鍵字overwrite
, 修改)的方法,能夠在方法定義前面添加final
關鍵字parent
關鍵字能夠可用於調用父類中被子類重寫了的方法self
關鍵字能夠用於訪問類自身的成員方法
,靜態成員和類常量;不能用於訪問類自身的屬性!!!使用常量的時候不須要在常量const
名稱前面添加$
符號static::
關鍵字用於訪問類自身定義的靜態成員,訪問靜態屬性時須要在屬性前面添加$
符號。const
不能使用對象訪問,僅能使用類訪問,在類本體內可使用「self::常量名
」,在類本體外可使用「類名::常量名
」 接口就是把不一樣類的共同行爲
進行定義,而後在不一樣的類裏面實現不一樣的功能
interface
定義接口,implements
用於表示類實現某個接口{}
instanceof
關鍵字判斷某個對象是否實現了某個接口 $object instanceof interface
interface extends interface
)必須是公有
,這是接口的特性 由於接口的方法實現能夠有不少,因此對於接口裏面定義的方法的具體實現是多種多樣的,這種特性咱們稱爲多態
不須要知道對象屬於哪一個類,只要判斷該對象的類是否實現接口,就能實現調用,相同代碼實現不一樣結果
形象點說就是同一個接口,不一樣的對象實現,得出的結果不同就是多態,如傳入的是人類對象,獲得的是人類吃蘋果,傳入的是猴子對象,獲得的就是猴子吃香蕉。相同的一行代碼,對於傳入不一樣的接口的實現的對象的時候,表現是不一樣的。
/** * 多態 * 1. 只要某個對象實現了接口(instanceof),就能夠直接在對象上調用接口的方法 */ interface ICanEat { public function eat($food); } // Human類實現了ICanEat接口 class Human implements ICanEat { // 跟Animal類的實現是不一樣的 public function eat($food){ echo "Human eating " . $food . "\n"; } } // Animal類實現了ICanEat接口 class Animal implements ICanEat { public function eat($food){ echo "Animal eating " . $food . "\n"; } } function eat($obj){ if($obj instanceof ICanEat){ $obj->eat("FOOD"); // 不須要知道究竟是Human仍是Animal,直接吃就好了 }else{ echo "Can't eat!\n"; } } $man = new Human(); $monkey = new Animal(); // 一樣的代碼,傳入接口的不一樣實現類的時候,表現不一樣。這就是爲何成爲多態的緣由。 eat($man); eat($monkey);
接口裏面的方法都是沒有實現的,而類裏面的方法都是有實現的。
有沒有一種形態,容許類裏面一部分方法不實現呢?
當接口中的某些方法對於全部的實現類都是同樣的實現方法,只有部分方法須要用到多態的特性
abstract
關鍵字用於定義抽象類abstract
關鍵字能夠標明這個方法是抽象方法不須要具體實現{}
extends
/** * 抽象類 * 1. 抽象類容許類裏面的部分方法暫時沒有具體實現,這些方法咱們成爲抽象方法 * 2. 一旦類裏面有抽象方法,這個類就必須是抽象類 * 3. 抽象類跟接口同樣,不能直接實例化爲對象 */ // 抽象類前面以abstract關鍵字開始 abstract class ACanEat { // 沒有實現的方法須要設定爲抽象方法 // 抽象方法須要在子類中實現 abstract public function eat($food); public function breath(){ echo "Breath use the air.\n"; } } // Human類實現了ICanEat接口 class Human extends ACanEat { // 跟Animal類的實現是不一樣的 public function eat($food){ echo "Human eating " . $food . "\n"; } } // Animal類實現了ICanEat接口 class Animal extends ACanEat { public function eat($food){ echo "Animal eating " . $food . "\n"; } } $man = new Human(); $man->eat("Apple"); $man->breath(); // 和Animal共用了抽象類ICanEat的breath方法 $monkey = new Animal(); $monkey->eat("Banana"); $monkey->breath();
__toString()
當對象被看成String使用時,這個方法會被自動調用(須要在類中定義__tostring()
方法。調用 echo $object__invoke()
當對象被看成方法調用時,這個方法會被自動調用(須要在類中定義__invoke()
方法)。調用 $object($parameter)/** * 魔術方法1 * 1. 當對象被當作String使用時,__toString()會被自動調用 * 2. 當對象被當成方法調用時,__invoke()會被自動調用 */ class MagicTest{ public function __toString(){ return "This is the Class MagicTest.\n"; } public function __invoke($x){ echo "__invoke called with parameter " . $x . "\n"; } } $obj = new MagicTest(); echo $obj; $obj(5);
__call()
方法:當對象訪問不存在的方法名稱時,此方法自動調用。
public function __call($name,$argument){}
public
;必須有兩個參數:對象訪問的方法名稱($name
)、方法包含的參數($argument
==> 自動轉換成數組)。__callStatic()
方法:當對象訪問不存在的靜態方法名稱時,此方法自動調用。
public static function __callStatic($name,$argument){}
__call()
;此方法爲靜態方法(static)。這兩種方法也被稱爲方法的重載(overloading
)
overwrite
)/** * 魔術方法之方法重載 * 1. 當對象訪問不存在的方法名稱時,__call()方法會被自動調用 * 2. 當對象訪問不存在的靜態方法名稱時,__callStatic()方法會被自動調用 */ class MagicTest{ /** * 自動將參數轉換成數組 * array (size=2) * 0 => string 'para1' (length=5) * 1 => string 'para2' (length=5) * @param $name * @param $arguments */ public function __call($name, $arguments){ var_dump($arguments); echo "Calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n"; } public static function __callStatic($name, $arguments){ echo "Static calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n"; } } $obj = new MagicTest(); $obj->runTest("para1", "para2"); MagicTest::runTest("para3","para4");
屬性
賦值時,__set()會被調用 定義function __set($name,$value) 讀取
不可訪問屬性的值時,__get()會被調用 定義function __get($name) isset()
或empty()
時,__isset()
會被調用unset()
時,__unset()
會被調用 這幾個方法也被成爲屬性重載
的魔術方法
所謂不可訪問屬性,實際上就是在調用某個屬性時發現這個屬性沒有被定義,這時候不一樣的操做會觸發不一樣的魔術方法
$obj1 = $ojb; //不能實現對象複製,兩個對象變量指向同一對象 $obj1 = clone $obj; //實現對象複製,變成值相同的兩個對象
調用clone
時會自動調用__clone()
方法
$james = new NbaPlayer(); //$ja0 對應內存地址(假設爲 address0 )中存儲的是 james對象的標識符 $james2 = clone $james; //當但願生成一個真正獨立存儲的 NbaPlayer() 對象,但新對象的全部數據都和 $james 對象中的相同時,使用關鍵字clone
當在class NbaPlayer()
中定義了 __clone()
方法 後,使用clone
關鍵字時,系統將調用用戶定義的__clone()
方法 (此時能夠對clone
後生成的新對象的屬性進行修改)
完!