1、對象的繼承php
1)什麼是繼承?數據庫
父類的內容能夠拿到子類當中來使用設計模式
2)爲何要使用繼承?數組
①更好地體現面向對象的可重用性網絡
②避免代碼的冗餘函數
③能夠在父類的基礎上進行功能的擴展this
④體現了面向對象的可擴展性spa
3)何時使用繼承?設計
①在功能要進行擴展的時候進行繼承code
②在功能要進行修改的時候,子類的功能會覆蓋父類的功能
4)PHP繼承的特性:
①只支持單一繼承,不支持多重繼承
②一個子類只容許有一個父類
③一個父類能夠有多個子類
5)PHP繼承的關鍵字
①父類、基類、超類
②子類、擴展類、派生類
6)權限問題
①public:公有的成員在子類中能夠被徹底繼承;子類中的成員若是與父類的公有成員的名稱相同,則子類的成員功能將覆蓋父類的成員功能;
②protected:受保護的成員在子類當中能夠被徹底繼承;受保護的成員在子類中若是出現同名的成員,功能會被覆蓋;
③private:父類中私有的成員在子類中不能直接拿來使用,不可被繼承
④private < protected < public,子類中的同名的成員的權限必定要比父類的成員的權限寬鬆
7)方法的重載(覆蓋)
parent::__construct();
parent::成員方法名();
class Person{ public $name; public $sex; public $age; function __construct($name,$sex,$age){ $this->name=$name; $this->sex=$sex; $this->age=$age; } public function say(){ echo "my name is ".$this->name.", my sex is ".$this->sex.", my age is ".$this->age; } } class Student extends Person{ //繼承成員屬性$name、$sex、$age public $school; //構造方法一樣被繼承,並被覆蓋重寫 function __construct($name,$sex,$age,$school){ //將父類的構造方法的方法體繼承下來 parent::__construct($name,$sex,$age); $this->school=$school; } //將父類的say方法覆蓋重寫 public function say(){ //將父類的say方法的方法體繼承下來 parent::say(); echo ", my shcool is ".$this->school; } } $p=new Student("autumn","男",25,"haha"); $p->say();
2、經常使用的關鍵字
1)final
①final修飾的成員方法不容許在子類當中被重寫,爲了防止已經寫好的功能被修改
②final只能修飾方法和類,不能修飾成員屬性
③final修飾的類不能再被其餘類繼承
2)static
①static修飾的成員屬性,在類的方法體中要使用「self::$屬性名稱」訪問
②static修飾的成員屬性保存在內存中的初始化靜態段中,而在類中使用「$this->屬性」所調用的成員屬性是保存在堆當中的,因此static修飾的成員屬性不能使用「$this->屬性名稱」來訪問
③靜態成員屬性在類的外部可經過「類名::$成員屬性名稱」調用,不可以使用對象來調用
④靜態成員屬性效率較高,由於不須要實例化對象便可調用
⑤同一個類的多個實例化對象共享一個靜態成員屬性
⑥靜態的成員方法中不容許使用$this調用成員屬性
⑦靜態的成員方法在類的內部可使用$this調用,也可使用「self::方法名()」調用
⑧靜態的成員方法在類的外部可使用實例化對象調用,也可使用「類名::方法名()」調用
⑨成員方法當中若是沒有包含任何$this,該方法默認爲靜態成員方法
class Person{ public $username; public static $name; public function info(){ //普通成員屬性的調用 //echo $this->username; //靜態成員屬性的調用 echo self::$name; } public static function say(){ echo self::$name." say 'hello world!'"; } public function test(){ //可使用$this調用靜態成員方法 //$this->say(); //也可以使用「self::方法名()」調用 self::say(); } } //靜態成員屬性不可使用對象來調用 $p1=new Person; Person::$name="autumn"; $p2=new Person; Person::$name="HaHa"; //多個實例化對象共享一個靜態成員屬性 $p1->info(); $p2->info(); echo "<hr>"; //能夠用實例化對象調用靜態成員方法 //$p1->say(); //也可使用「類名::方法名()」調用(推薦使用) Person::say();
3)單態設計模式
①什麼是單態(單例)(單對象)設計模式?
讓類只能實例化一個對象
②爲何要使用單態?
爲了節省空間、提升效率
③何時使用單態設計模式?
數據庫的鏈接池操做、文件資源的操做、GD資源的操做
④如何使用單態設計模式?
1.構造方法私有化,外部沒法自動實例化對象
2.聲明一個方法,在該方法中實例化對象
3.將產生的對象存入至一個共享的靜態成員屬性中
4.在外部想要再次實例化對象時,將該靜態成員屬性中的對象傳給它,即仍爲首次實例化的那個對象
class Person{ public static $obj; //用於保存首次實例化的對象 public $name; //構造方法私有化,外部沒法自動實例化對象 private function __construct($name){ $this->name=$name; } public static function getObj($name){ //判斷該類的對象是否存在 if(is_null(self::$obj)){ self::$obj=new self($name); } //除首次實例化對象外,其他直接將首次實例化後存在靜態成員屬性中的對象傳遞過去 return self::$obj; } public function info(){ echo $this->name; } } $p1=Person::getObj("autumn"); var_dump($p1); echo "<hr>"; $p2=Person::getObj("haha"); var_dump($p2);
object(Person)#1 (1) { ["name"]=> string(6) "autumn" }
object(Person)#1 (1) { ["name"]=> string(6) "autumn" }
4)const
①常量名通常狀況下用大寫
②常量值爲標量數據類型
③常量不要加「$」
④常量在類的內部訪問用「self::常量名」
⑤常量在類的外部訪問用「類名::常量名」
5)instanceof
①判斷一個對象是否爲一個類實例化的
②判斷一個對象是否爲繼承父類的某個子類實例化的
class Person{ //聲明一個常量成員屬性 const DB_HOST="localhost"; public function info(){ //類的內部調用常量成員屬性 echo self::DB_HOST; } } class Student extends Person{ public $school="hehe"; public function say(){ parent::info(); echo ", my school is ".$this->school; } } //類的外部調用常量成員屬性 echo Person::DB_HOST; echo "<hr>"; $p=new Person; $s=new Student; //instanceof用於檢測當前實例對象是否屬於某一個類 var_dump($p instanceof Student); //false var_dump($s instanceof Student); //true var_dump($s instanceof Person); //true
3、經常使用的魔術方法
1)克隆對象
①什麼是克隆?
將一個對象完整的複製一份,這個對象與原對象如出一轍
②克隆的目的
當對一個已經產生的對象進行一系列的修改、賦值等操做後,須要使用多個經操做後的對象時,使用克隆
③方法:__clone()
參數:無
觸發時機:在使用clone對象的一瞬間自動調用
做用:將克隆出的對象進行微調,源對象不會被影響
2)__toString()
參數:無
觸發時機:當在類的外部直接echo對象時,自動調用
做用:爲了更好地操做對象
注意:本方法必定要有返回值
3)__call()
參數:兩個(第一個是調用方法的名稱,第二個是實際參數的數組)
觸發時機:當調用一個不存在的成員方法時自動調用,且將方法的名稱傳遞給第一個參數,將方法的調用參數傳遞給第二個參數
做用:避免程序報錯,影響後續代碼執行
class Person{ private $name="autumn"; private $sex="男"; private $age=25; public function info(){ echo "姓名:".$this->name.",性別:".$this->sex.",年齡:".$this->age; } //在使用clone對象的瞬間自動調用__clone()方法 function __clone(){ $this->name=$this->name."_clone001"; } //在類的外部echo對象時自動調用__toString()方法 function __toString(){ return "在類的外部直接echo對象會輸出該段文字"; } //當調用一個不存在的成員方法時自動調用__call()方法 function __call($funcName,$args){ echo "對不起,您要找的方法".$funcName."(".join(',',$args).")不存在!"; } } $p1=new Person; //將對象$p1完整克隆一份 $p2=clone $p1; var_dump($p1); echo "<hr>"; var_dump($p2); echo "<hr>"; echo $p1; echo "<hr>"; $p1->noFunc('參數1','參數2','參數3');
4)__sleep()
參數:無
觸發時機:當對一個對象序列化的時候自動調用
做用:讓用戶能夠自定義要序列化的成員屬性
注意:該方法必定要返回一個數組類型的值,數組元素的值即爲成員屬性的名稱
5)__wakeup()
參數:無
觸發時機:當對對象進行反序列化的時候自動調用
做用:反序列化對象時使對象中的成員發生改變
6)對象串行化(序列化)
將對象轉化成以固定形式存儲的字符串
①爲何使用對象的串行化?
爲了可以讓保存對象的介質可以識別對象的格式
②什麼時候使用對象的串行化?
要將對象存入到數據庫或是文件中
對象在網絡中傳輸的時候可串行化
③方法:
serialize($obj):串行化(序列化)
unserialize($str):反串行化(反序列化),將對象反串行化時必須有原型類同時在
class Person{ private $name="autumn"; private $sex="男"; private $age=25; public function info(){ echo "姓名:".$this->name.",性別:".$this->sex.",年齡:".$this->age; } public function __sleep(){ //指定要序列化的成員屬性 return array('name','sex'); } } $p=new Person; echo $str=serialize($p); file_put_contents("./obj.txt",$str);
class Person{ private $name="autumn"; private $sex="男"; private $age=25; public function info(){ echo "姓名:".$this->name.",性別:".$this->sex.",年齡:".$this->age; } public function __sleep(){ //指定要序列化的成員屬性 return array('name','sex'); } public function __wakeup(){ $this->name="admin"; $this->sex="保密"; } public function say(){ echo "haha"; } } $str=file_get_contents("./obj.txt"); //將對象反序列化時,必需要原對象類同時在 $obj=unserialize($str); $obj->info();
7)__autoload()
參數:一個(類的名稱)
觸發時機:當要實例化或繼承使用未經include引入的類文件中的類的時候會自動調用該函數,且會將類名做爲參數傳入該函數,此時在該函數內部可實現類文件的加載
做用:用於加載類文件,無需像使用include加載類文件那樣考慮加載的前後順序
注意:這是一個函數並不是是類的成員方法,不是用於類的內部的,而是在須要引用類文件時使用的
function __autoload($className){ if($className=='class1'){ include "../".$className.".class.php"; }elseif($className=='class2'){ include "../".$className.".class.php"; }elseif($className=='class3'){ include "./".$className.".class.php"; } } $p=new Person;
4、類型約束
1)類型約束可使用數組約束和類名約束
2)數組約束:只須要在方法或函數的參數前加入array關鍵字便可
3)類名約束:只須要在方法或函數的參數前加入類名,表示調用時必須傳遞該類的對象或該類的子類的對象
class Person1{ function say(array $info){ //數組約束 echo "P1:".join(',',$info); } } class Person2{ function say(array $info){ //數組約束 echo "P2:".join(',',$info); } } class Person{ function test(Person1 $obj){ //類名約束 $obj->say(array('abc','ABC')); } } $p=new Person; $p->test(new Person1);