面向對象並非一種技術,而是一種思想,是一種解決問題的最基本的思惟方式!如何理解使用?OOP:面向對象編程php
(直接代碼說明)html
1.面向對象的基本概念 示例demo:編程
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //如何類的實例化? 例如: $newA= new a(); 利用類獲得對象,過程是類的實例化.關鍵字new完成. 4 //如何定義一個類? 例如: class a{} 類 5 //如何聲明定義屬性? 例如: public $age 屬性 聲明的控制修飾符:1.public 2.protected 3.private 6 //如何聲明定義方法? 例如: public function user(){} 方法 對象成員(屬性,方法)的訪問符:-> 7 //如何定義類常量? 例如: const WORK = 'php'; 類常量 訪問形式: 類名::常量名 8 //小結: 一個類中只有三個成員:1.屬性(變量) 2.方法(函數) 3.類常量(常量) 9 class a{//類 10 public $name;//屬性 11 public $age; 12 const WORK = 'php';//類常量 13 public function user($object){//方法 14 echo '名字:'.$object->name.'年齡:'.$object->age.'工做'.self::WORK;//在一個類的內部,使用關鍵字self代替"當前類名" 15 } 16 } 17 $newA = new a();//實例化對象 ==> class a{} 18 $newA->name='admin_a'; 19 $newA->age = 100; 20 $newA->user($newA); 21 22 23 //如何使用$this? 例如: $this表明當前所屬類的"當前對象" ,當前誰調用,誰就是"當前對象" 24 //小結: 屬性不能在方法內直接訪問,須要先找到其對象才能訪問,典型的作法就是在方法內使用$this關鍵字來代替當前對象. 25 class b{ 26 public $name; 27 public $age; 28 const WORK = 'html'; 29 public function user(){ 30 echo '名字:'.$this->name.'年齡:'.$this->age.'工做'.self::WORK;//$this當前對象 31 } 32 } 33 echo "<pre>"; 34 $newB = new b(); 35 $newB->name='admin_b'; 36 $newB->age = 200; 37 $newB->user($newB);
運行結果以下圖:函數
1 $this 和 self 的區別? 2 3 一個是對象$this 至關於實例化後,能夠說除了靜態和const常量,基本上均可以使用this聯絡 4 5 self則是類自己 self能夠訪問本類中的靜態屬性和靜態方法,能夠訪問父類中的靜態屬性和靜態方法。用self時,能夠不用實例化.
2.面向對象中的魔術方法,__construct():構造方法 示例demo this
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //PHP提供__開頭的函數,這些函數無需本身手動調用,會在合適的時機自動調用,這類函數稱爲魔術函數。 4 //__construct():構造方法 new對象時自動調用 5 class a{ 6 public $name; 7 public $age; 8 const WORK = 'php'; 9 public function __construct($user_name,$user_age){//構造方法 10 $this->name=$user_name; 11 $this->age=$user_age; 12 } 13 14 public function user(){ 15 echo '使用構造方法: 名字:'.$this->name.'年齡:'.$this->age.'工做:'.self::WORK; 16 } 17 } 18 19 $userA= new a('admin_a',100);//對象的屬性進行初始化 20 $userA->user(); 21 22 $userB= new a('admin_b',200);//對象的屬性進行初始化 23 echo '<pre>'; 24 var_dump($userA,$userB);
運行結果以下圖:spa
3.面向對象中的魔術方法,__destruct():析構方法 示例demo日誌
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //PHP提供__開頭的函數,這些函數無需本身手動調用,會在合適的時機自動調用,這類函數稱爲魔術函數。 4 //__destruct():析構方法 當刪除一個對象或一個對象操做結束時被自動調用.(當一個對象被銷燬前自動調用) 5 class a{ 6 public $name; 7 public $age; 8 const WORK = 'php'; 9 public function __construct($user_name,$user_age){//構造方法 10 $this->name=$user_name; 11 $this->age=$user_age; 12 } 13 14 public function __destruct(){//析構方法 15 echo '<pre>'.'銷燬前自動調用:'.$this->name; 16 } 17 18 public function user(){ 19 echo '使用構造方法: 名字:'.$this->name.'年齡:'.$this->age.'工做:'.self::WORK; 20 } 21 } 22 23 $userA= new a('admin_a',100);//對象的屬性進行初始化 24 $userA->user(); 25 $userA= NULL; 26 27 $userB = new a('admin_b',200); 28 echo '<pre>'; 29 var_dump($userA,$userB);
運行結果以下圖:code
4.面向對象中的魔術方法,__clone() 示例demohtm
1 <?php 2 //__clone():當使用clone關鍵字,克隆一個對象時自動調用,做用是爲新克隆的對象初始化賦值 3 class a{ 4 public $name; 5 public $age; 6 public function __construct($user_name,$user_age){ 7 $this->name=$user_name; 8 $this->age=$user_age; 9 } 10 11 public function __clone(){ 12 $this->name='admin_b'; 13 $this->age=200; 14 } 15 } 16 17 $userA= new a('admin_a',100); 18 $userB = clone $userA;//克隆新對象 19 echo '<pre>'; 20 var_dump($userA,$userB);
運行結果以下圖:對象
5.靜態成員(包含靜態屬性和靜態方法) 示例demo
類中的全部成員:1.非靜態屬性 2.靜態屬性 3.非靜態方法 4.靜態方法 5.類常量
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //靜態成員的定義,名字前面加上關鍵字static. 靜態成員包含1.靜態屬性 2.靜態方法 4 //靜態屬性類內,類外是如何方法? 5 class a{ 6 public $name; 7 public static $age =100; 8 const WORK = 'php'; 9 public function __construct($user_name){ 10 $this->name=$user_name; 11 } 12 13 public function user(){ 14 //靜態屬性訪問 //常量訪問 15 echo '名字:'.$this->name.' (靜態屬性類內訪問) 年齡:'.self::$age.' 工做:'.self::WORK; 16 } 17 } 18 19 $userA= new a('admin_a'); 20 $userA->user(); 21 echo '<pre>(靜態屬性類外訪問) 年齡:'.a::$age; 22 23 24 //靜態方法類內,類外如何訪問? 25 class b{ 26 public function f1(){ 27 echo '非靜態方法f1()'; 28 } 29 30 public static function f2(){ 31 echo '靜態方法f2()'; 32 } 33 34 public static function f3(){ 35 self::f2(); 36 } 37 } 38 echo '<pre>'; 39 $newB=new b(); 40 $newB->f1(); 41 echo '<pre>(靜態方法類外訪問) '; 42 echo b::f2(); 43 echo '<pre>(靜態方法類內訪問)'; 44 echo b::f3();
運行結果以下圖:
6. 類文件的自動 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //類文件的自動加載:自動調用__autoload()函數,該函數傳遞一個參數是當前類的類名 4 //簡單實現自動加載 5 function __autoload($class_name){ 6 if(file_exists($class_name.'.class.php')){ 7 //加載類文件 8 include $class_name.'.class.php'; 9 }else{ 10 return false; 11 } 12 } 13 //實例化自動加載__autoload()函數 14 $newA= new a('admin_a',100); 15 $newA->user();
a.class.php文件
1 <?php 2 class a{ 3 public $name; 4 public $age; 5 const WORK = 'php'; 6 public function __construct($user_name,$user_age){ 7 $this->name=$user_name; 8 $this->age=$user_age; 9 } 10 public function user(){ 11 echo '自動加載類文件獲取: 名字:'.$this->name.'年齡:'.$this->age.'工做:'.self::WORK; 12 } 13 }
運行結果以下圖:
7.類的繼承 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //類的繼承: 一個類從另外一個已有的類得到其成員的相關特性. 實現繼承關鍵字:extends 4 //派生: 一個已有的類產生一個新的類,稱爲派生.(好比:B類繼承自A類,反過來A類派生出B類) 5 //父類: 也叫做基類,就是指已有被繼承的類 6 //子類: 也叫做派生類或擴展類 7 //擴展:在子類中增長一些本身特有的特性,就叫做擴展 8 //單繼承: 一個類只能繼承自一個其餘的類,不能繼承多個類.(重點) 9 //面向對象有三大特性:1.繼承性 2.多態性 3.封裝性 10 class goods{ 11 public $goods_id; 12 public $goods_name; 13 } 14 15 class book extends goods{ 16 public $area; 17 public $type; 18 } 19 20 class manga extends book{ 21 public $author; 22 public $title; 23 public function __construct($goods_id,$goods_name,$type,$area,$author,$title){ 24 $this->goods_id=$goods_id; 25 $this->goods_name=$goods_name; 26 $this->type=$type; 27 $this->area=$area; 28 $this->author=$author; 29 $this->title=$title; 30 } 31 } 32 echo '<pre>'; 33 $manga =new manga('1000','書籍類','中國地區','漫畫','米二','一人之下'); 34 print_r($manga);
運行結果以下圖:
8.重寫 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //重寫(覆蓋):當子類成員與父類成員名字相同,從父類繼承下來的成員會從新定義.(真正做用是子類中定義的成員!) 4 //語法: 父類名::父類的構造方法 關鍵字parent: 表明的是其父類 (經常使用寫法) 5 class Goods{ 6 public $goods_name; 7 //構造方法 繼承類都使用構造方法,如何解決重寫(覆蓋)問題? 8 public function __construct($g_name){ 9 $this->goods_name=$g_name; 10 } 11 public function getName(){ 12 echo $this->goods_name; 13 } 14 } 15 16 class Book extends Goods{ 17 public $type; 18 } 19 20 class Manga extends Book{ 21 public $title; 22 //先執行子類構造方法,後執行父類構造方法 23 public function __construct($g_name,$m_title){ 24 //調用父類的構造方法並傳遞變量 25 parent::__construct($g_name); 26 $this->title=$m_title; 27 } 28 public function getName(){ 29 echo 'Goods父類:'; 30 //調用父類getName()方法 31 Goods::getName(); 32 echo '<hr>'; 33 echo 'Manga子類:'; 34 echo $this->title; 35 } 36 } 37 38 $manga = new Manga('商品名稱','一人之下'); 39 $manga->getName();
運行結果以下圖:
9.最終類和抽象類 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //final類:最終類,不能被繼承,只能實例化對象的類! 使用關鍵字:final 4 //abstract類:抽象類,只能被繼承,不能實例化對象的類! 使用關鍵字:abstract 5 //final類 示例demo 6 class commodity{ 7 public $commodity_id; 8 public $commodity_name; 9 } 10 11 final class book extends commodity{//實際開發過程當中的規範 12 public $area; 13 public $type; 14 } 15 $book = new book(); 16 echo '<pre>'; 17 print_r($book); 18 19 //abstract類 示例demo 20 abstract class goods{ 21 public $goods_id; 22 public $goods_name; 23 abstract function type($data); 24 abstract function area(); 25 } 26 27 class manga extends goods{ 28 public $author; 29 public $title; 30 function type($data){ 31 echo $data; 32 } 33 function area(){} 34 } 35 $manga= new manga(); 36 $manga->type('實現type()方法');
運行結果以下圖:
10.interface接口 示例demo
1 <?php 2 header("Content-Type: text/html;charset=utf-8"); 3 //接口: 若是一個類中,全部的方法都是抽象方法,且成員屬性必須是常量,這類被稱爲接口. 關鍵字:interface 4 //接口的做用:雖然PHP的類是單繼承,但能夠經過接口來實現多繼承。 5 interface User{ 6 //接口的屬性必須是常量 7 const VIP = 'vip用戶'; 8 public function getDiscount(); 9 } 10 11 class VipUser implements User{ 12 //vip折扣係數 13 private $discount = 0.6; 14 public function getDiscount() { 15 return $this->discount; 16 } 17 } 18 19 class Goods{ 20 private $price = 200; 21 private $objectUser; 22 //獲取User接口VipUser類實現 23 public function getUserData($User){ 24 $this->objectUser = $User; 25 $discount = $this->objectUser->getDiscount(); 26 $usertype = User::VIP; 27 echo $usertype."=>商品價格:".$this->price*$discount; 28 } 29 } 30 31 $display = new Goods(); 32 $display ->getUserData(new VipUser);
運行結果以下圖:
11.魔術方法和魔術常量概念小結
1 語法較多就不一一舉例,更多信息能夠去查php手冊用法. 2 3 魔術方法 4 PHP中把以兩個下劃線__開頭的方法稱爲魔術方法包括: 5 __construct() :類的構造函數 (經常使用) 6 7 __destruct() :類的析構函數 8 9 __call() :在對象中調用一個不可訪問方法時調用 10 11 __callStatic() :用靜態方式中調用一個不可訪問方法時調用 12 13 __get() :得到一個類的成員變量時調用 14 15 __set() :設置一個類的成員變量時調用 16 17 __isset() :當對不可訪問屬性調用isset()或empty()時調用 18 19 __unset() :當對不可訪問屬性調用unset()時被調用 20 21 __sleep() :執行serialize()時,先會調用這個函數 22 23 __wakeup() :執行unserialize()時,先會調用這個函數 24 25 __toString() :類被當成字符串時的迴應方法 26 27 __invoke() :調用函數的方式調用一個對象時的迴應方法 28 29 __set_state() :調用var_export()導出類時,此靜態方法會被調用 30 31 __clone() :當對象複製完成時調用 32 33 34 魔術常量 35 魔術常量常被用於得到當前環境信息或者記錄日誌等.魔術常量包括: 36 37 __LINE__ :文件中的當前行號 38 39 __FILE__ :文件的完整路徑和文件名 40 41 __DIR__ :文件所在的目錄 42 43 __FUNCTION__ :函數名稱 44 45 __CLASS__ :類的名稱 46 47 __TRAIT__ :Trait的名字 48 49 __METHOD__ :類的方法名 50 51 __NAMESPACE__ :當前命名空間的名稱
12.命名空間的概念和使用 示例demo:
1 <?php 2 //命名空間:一個腳本的開始須要定義命名空間,必須在腳本的最開始處定義. 關鍵字:namespace 3 //空間成員包含:1.常量 2.函數 3.類 4 //定義命名空間One 5 namespace One; 6 header("Content-Type: text/html;charset=utf-8"); 7 function getName(){//函數 8 echo '空間:'.__NAMESPACE__; 9 } 10 const AGE=100;//常量 11 class User{//類 12 public $name='admin_a'; 13 } 14 getName(); 15 echo '年齡:'.AGE; 16 var_dump(new User); 17 echo "<hr/>"; 18 19 //定義命名空間Two 20 namespace Two; 21 function getName(){ 22 echo '空間:'.__NAMESPACE__; 23 } 24 const AGE=200; 25 class User{ 26 public $name='admin_b'; 27 } 28 getName(); 29 echo '年齡:'.AGE; 30 var_dump(new \Two\User);//注意:徹底限定名稱訪問
運行結果以下圖:
1 <?php 2 //三種訪問空間成員的方式:1.非限定名稱訪問 2.限定名稱訪問 3.徹底限定名稱訪問 "\":表明根空間 3 //(1)非限定名稱訪問:在訪問空間成員的時候,沒有指定具體的空間的名字. 4 namespace A\B\C\D; 5 header("Content-Type: text/html;charset=utf-8"); 6 function getName(){ 7 echo '空間:'.__NAMESPACE__; 8 } 9 const AGE=100; 10 class User{ 11 public $name='admin_a'; 12 } 13 echo '空間A\B\C\D 非限定名稱訪問: '; 14 getName(); 15 echo '年齡:'.AGE; 16 var_dump(new User); 17 echo "<hr/>"; 18 19 //(2)限定名稱訪問:就是從當前空間開始訪問其子空間的成員. 語法:子空間名\空間成員名 20 namespace A\B\C; 21 function getName(){ 22 echo '空間:'.__NAMESPACE__; 23 } 24 const AGE=200; 25 echo '空間A\B\C 非限定名稱訪問: '; 26 getName(); 27 echo '年齡:'.AGE.'<br>'; 28 29 echo '空間A\B\C 限定名稱訪問: '; 30 D\getName();//限定名稱訪問 31 echo '年齡:'.D\AGE;//限定名稱訪問 32 var_dump(new D\User);//限定名稱訪問 33 echo "<hr/>"; 34 35 //(3)徹底限定名稱訪問:直接從根空間開始對絕對路徑訪問. 語法:\空間1\空間2\...\空間成員 36 //注意:徹底限定名稱訪問的最大好處是能夠在任意的空間訪問其餘任意空間的成員. 37 //空間類的引入語法: use 空間名\類名 38 namespace A; 39 function getName(){ 40 echo '空間:'.__NAMESPACE__; 41 } 42 const AGE=300; 43 echo '空間A 非限定名稱訪問: '; 44 getName(); 45 echo '年齡:'.AGE.'<br>'; 46 47 echo '空間A 徹底限定名稱訪問: '; 48 \A\B\C\D\getName();//徹底限定名稱訪問 49 echo '年齡:'.\A\B\C\D\AGE;//徹底限定名稱訪問 50 use A\B\C\D\User;//空間類的引入 51 var_dump(new User);
運行結果以下圖:
空間類的引入 示例demo:
文件One.php
1 <?php 2 namespace One; 3 header("Content-Type: text/html;charset=utf-8"); 4 function getName(){ 5 echo '空間:'.__NAMESPACE__; 6 } 7 class User{ 8 public $name='admin_a'; 9 } 10 class Book{ 11 public $manga='一人之下漫畫'; 12 }
文件Two.php
1 <?php 2 //空間類的引入:就是把其餘空間的類,引入到當前空間. 語法:use 空間名\類名 3 namespace Two; 4 header("Content-Type: text/html;charset=utf-8"); 5 function getName(){ 6 echo '空間:'.__NAMESPACE__; 7 } 8 class User{ 9 public $name='admin_b'; 10 } 11 //引入文件 12 include 'One.php'; 13 getName();//打印結果:空間:Two 14 echo '<pre>'; 15 16 //將One空間裏面Book類引入到當前空間 17 use \One\Book; 18 //將One空間裏面User類引入到當前空間(注意使用別名:oneUser) 19 use \One\User as oneUser; 20 $oneBook= new Book(); 21 $oneUser= new oneUser(); 22 //使用當前空間類 23 $twoUser= new User(); 24 var_dump($oneBook,$oneUser,$twoUser);
運行結果以下圖: