【編程開發】PHP---面向對象
面向對象編程
類:在現實世界中,任何事物都有種類的概念:車
類是由特征和行為構成的。
特征:都是不動的,從出廠的時候就已經內置好了(屬性)
行為:一種動的狀態。(方法(函數))
行為依賴於這些特征,而特征只有通過這些行為才能施展。
對象調用屬性、方法
<?php header("Content-Type:text/html; charset=utf-8"); class Persion{ const NAME = "小王"; public $name = "小明"; //public訪問控制符 public $name1 = "小紅";public function run($my_nume){ echo $my_nume; } } //對象調用屬性 以及方法 使用-> //對象調用屬性的時候,直接加屬性名,不要加$符 //對象調用方法的時候,直接寫方法名就可以了 //調用類常量,可以用當前對象,加::的形式來調用 $p = new Persion(); //返回的是一個對象 echo $p->name; $p->run("小藍"); echo $p::NAME; echo Persion::NAME; //也通過直接調用當前類 加::的形式來調用
類常量:const
const用於類成員常量的定義,一經定義,不可修改。
const和define的區別:
1、const可以在類中使用,define不能
2、const不能在條件語句中定義常量
☆ const定義的常量是大小寫敏感,而define可以通第三個參數來指定大小寫是否敏感。
構造函數:__construct()
我們在創建一個類的時候有時候需要初始化一些操作,這個時候我們需要使用初始化函數,在PHP中有兩種初始化方法:
1、構造函數:__construct() 。註意:構造函數是自動運行的,在你實例化的時候就自動執行了。
class MyPc { function __construct(){//初始化操作 } } new MyPc();
構造函數怎麽傳遞參數呢?通過在類名實例化的小括號裏傳遞我們的參數:
class MyPc{ function __construct($name) { echo ‘你好‘.$name; } } new MyPc("小王");
2、建立一個對象方法
註意:此時測方法名沒有大小寫區分,只要與類名一致,均會被當成構造函數,在實例化時自動調用。
class MyPc { function MyPc(){ //當方法名跟我們的類名一致的時候,PHP就會自動的把它當成構造函數來使用 echo "123"; } } new MyPc();
註意:
__construct的優先級比對象方法高,當類中有__construct時必須放在類的開頭。
class MyPc{ function __construct($name) { //如果用__construct方法,則必須放在類中的開頭 echo ‘你好‘.$name; } function MyPc() { //此時的MyPc()方法就是一個普通的方法 echo "asd"; } } (new MyPc("小王"))->MyPc(); //此時要實例化類,則必須傳入一個參數,因為構造函數定義的時候需要一個參數,之後由於沒有定義一個參數來賦值類,所以用括號擴起來。
析構函數:__destruct() 了解就好
能夠在對象釋放時自動被調用的方法被稱為析構函數。
理解:
我們可以理解為垃圾回收機制,當對象內部的操作執行完畢的時候,__destruct()被調用,然後對象所使用的內存被釋放出來。
規則:
先進先出
$this 關鍵字
$this關鍵字:是用來訪問當前對象中的對象屬性和對象方法的系統變量
理解:
我們可以理解為$this是在對象中特殊的一種使用構造函數和變量的方法。
註意:$this僅能在當前對象中使用
class Pc{ public $name = "小馬"; function computer($name=‘小明‘,$c=‘‘) { $this->name = $name; //可以動態的修改類的屬性,第一個name不加$,表示類的屬性 //第二個是傳入的參數 echo $this->name; //在類的裏面,調用其他屬性和方法用$this //用$this加->調用屬性和方法 //註意,這裏的name不用加$符號 } } //類不被實例化,是不會展示類裏面所有功能的。 $p = new Pc(); $p->computer(); //這裏沒有傳遞參數,則定義時必須給形參一個默認值
類成員的訪問控制
訪問控制符:
就是把一些相關的屬性和行為隱藏起來,從而得到保護和安全。
public:
表示全局,在類的內部和外部子類都可以訪問。
protected:
表示受保護的,只有本類或子類或父類中使用。
private:
表示私有,只有本類內部可以使用。
☆ 類,是要被實例化返回一個對象的,在對象訪問的時候,訪問屬性和方法只能用public來訪問,不能用其他兩個。即無法用->來訪問proteced和private的屬性和方法。
class Pc{ public $name = "小馬"; protected $age = ‘18‘; //受保護的,在本類中可以使用$this->來調用,但是在外部實例化的時候是不能調用的 //可繼承 private $city = ‘上海‘; public function test() { return $this->name."在".$this->city; //方法最好有返回值熱,retur和echo都可以,建議用return //$this 調用本類的屬性和方法 } } //類的外面想要調用屬性,要先實例化該類 $p = new Pc(); /*echo $p->name; //正常調用 echo $p->age; //Fatal error: Cannot access protected property echo $p->city; //Fatal error: Cannot access private property */ echo $p->test();
類的自動加載:__autoload()
使用"__"開頭的基本上都是系統的構造函數
作用:
快速取得對象名稱並自動載入進當前頁面,當實例化類的時候,會自動獲取類的名稱,並在當前文件中及當前文件目錄下自動加載
<?php header("Content-Type:text/html; charset=utf-8"); //類的自動加載 //自動加載函數,可以放到類的外面,執行該文件的時候會自動執行 function __autoload($class_name){ include($class_name.".php"); //如果本文件中沒有這個類,那麽會在本文件目錄下自動加載以該類名稱命名的文件 } $p = new Pc(); echo $p->name; #$p = new MyPc(); //如果本文件中沒有這個類,那麽會在本文件目錄下自動加載以該類名稱命名的文件 class Pc { public $name = "adf"; }
類的繼承:extends
PHP類的繼承,我們可以理解成共享被繼承類的內容。PHP中使用extends單一繼承的方法,請切記:(非C++多繼承)被繼承的類我們叫做父類(基類),繼承者稱為子類(派生類)。
PHP繼承的規則:
可多重繼承,但是不能同時繼承多個。可避免屬性和方法的重名。
關鍵字:patent
子類(派生類)繼承父類(基類)。子類想訪問跟子類方法同名的父類的時候,並且子類的方法也不想被方法重載的時候。這時候使用parent。
在類中定義方法的時候,如果不寫訪問控制符,那麽默認是public屬性。
//基類、父類 class A { function test(){ echo "父類"; } } class B extends A { function test() { #echo "子類"; parent::test(); } } $p = new B(); $p->test(); //如果子類中的方法名與父類中的方法名重復,那麽子類的方法會覆蓋父類中的方法。(方法的重載)
當子類和父類的方法重名的時候,由於直接調用方法會默認調用子類的方法,因此我們使用parent關鍵字來調用父類中的方法。(在子類中使用)
方法重載
基類方法重載:
因為屬於向下繼承的原理,基類不能使用派生類裏的內容,這時基類的一些方法不能完成我們的一些派生類的功能。
我們就可以進行方法重載,避免新建方法帶來的混亂。
理解:方法重載我們也可以理解為方法覆蓋,在派生類中使用與基類方法重名的方法名來執行重載。
例子與上面parent一樣。
範圍操作符: "::"
註意:這個符號用於類中(而不是對象中)訪問成員,對象訪問成員使用的是"->"符號。
使用場景:
1、在使用類的時候,父類和子類具有相同的屬性和方法時,利用它可以避免混淆。
2、在類外的時候,沒有創建對象的情況下使用該操作符訪問類的成員。
記住:
在多數情況下,我們使用範圍解析操作符是為了訪問被重寫的方法。我們也可以用其訪問靜態和常數成員。
//基類、父類 class A { const Name=‘小明‘; public static function test() { echo "靜態方法"; } public function aa() { } } //調取類常量 echo A::Name; A::test(); //加::來調用一些靜態的屬性和方法 A::aa(); //不可以調用普通的方法名,Non-static method A::aa() should not be called statically
註意:不允許直接調用普通方法。
靜態成員的作用
靜態:只要在成員前加上關鍵字static,該變量就成為靜態成員了。
1、靜態變量屬於類,而不屬於類的某個實例。這個變量對所有實例都有效。
2、聲明為static的類、函數和變量將不能引用實例方法或變量。
3、靜態變量和方法必須通過類名進行引用而不能通過實例對象引用。
//基類、父類 class A { public static function test() { echo "這是一個普通方法"; } } //調用靜態的,無論是方法還是屬性,都可以用:: A::test();
匿名類 (了解即可,PHP7新加入的)
PHP7支持通過new class來實例化一個匿名類,這可以用來替代一些“用後即焚”的完整類定義。
trait技術
Traits是一種為類似PHP的單繼承語言而準備的代碼復用機制。Trait為了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類中復用方法集。
作用:我們在沒有增加代碼復雜的情況下,實現了代碼的復用。
trait類可以理解為復制粘貼類,由trait關鍵字定義,用use關鍵字調用(粘貼)。
//基類、父類 trait Pc { public function usb() { echo "usb"; } function key() { echo "key"; } } //trati類、復制粘貼類 class A { use Pc; } $a = new A(); $a->key();
問題:trait類和繼承類有什麽區別 ???
抽象類:abstract(類似純虛函數,純虛函數的定義是在虛函數定義的基礎上,再讓函數等於0即可)
抽象就是無法確切的說明,但又有一定的概念或者名稱,在PHP中聲明一個抽象類或者方法我們需要使用abstract關鍵字。
定義:
一個類中至少有一個方法是抽象的,我們稱之為抽象類。所以如果定義抽象類首先定義抽象方法。
總結:
1、類中至少有一個抽象方法,可以有其他普通方法。
2、抽象方法不允許有{ },即不能有方法體。
3、抽象方法前面必須加abstract。
幾個特點:
1、不能被實例化,只能被繼承。
2、繼承的派生類當中要把所有的抽象方法重載才能實例化。
abstract class A { abstract function usb(); function test(){ } } #new A();
//抽象類不能被實例化 //Cannot instantiate abstract class A class B extends A{ function usb(){ echo "子類重載"; } //如果沒有重載抽象類中的所有抽象方法,會出現以下報錯 //Class B contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (A::useb) } $b = new b(); $b->usb();
☆派生類裏面必須實現抽象類裏面的所有方法,少了一個都不行。
接口:interface(類似C++的抽象類,但是C++抽象類的定義是:包含由純虛函數的類被稱為抽象類)
接口:一種成員屬性全部為抽象的特殊抽象類,在程序中同為規範的作用。
接口的引用:
接口引用區別之前我們學的繼承關鍵字extends,繼承只能是單一性,而接口可以使用關鍵字:implement引用多個引用並用逗號“,”分開。
interface Pc { //接口類的所有方法都是抽象方法 //所有抽象方法都必須是public屬性,默認是publi。 function key(); function usb($name); } interface person{ public function age(); public function name($p_name); } //接口類只允許被實現和引用 //接口允許多引用,然後用“,”分開就行 class B implements Pc,person { //如果要實現接口類,要把接口類裏面的所有抽象方法都給實現 //少一個都不行 function key(){ } function usb($name){ echo "這是一個參數".$name; } function age(){ echo "18"; } function name($p_name){ echo "名字是:".$p_name; } } $b = new B(); #b->usb("鼠標"); $b->age(); $b->name("小紅");
關鍵字:self:
self用來訪問當前類的內容的關鍵字,類似於$this關鍵字,但$this是需要類實例化以後才可以使用,self可以直接訪問當前類中的內部成員。
註意:
因為沒有實例化類訪問內部屬性或者方法是沒有意義的,
所以self一般用來訪問類中的:靜態成員,常量,或者其他定義內容。
關鍵字:final
final是用來定義類和方法的一個重要關鍵字,當定義類的時候該類將不能被繼承,當用來定義方法的時候該方法將不能被重載。
//使用final關鍵字,A類將不被任何類繼承 #final class A class A { public $name = "小明"; //如果不想父類的方法被重寫,使用final關鍵字 final public function test(){ echo "父類"; } } //此時B類繼承A類將會報錯:Class B may not inherit from final class (A) class B extends A { //此時父類方法使用final關鍵字,子類就不能再進行重載了,會報錯:Cannot override final method A::test() public function test() { echo $this->name; } } $a = new B(); $a->test();
對象復制與克隆
產生背景:
有時候我們需要在一個項目裏面使用兩個或多個一樣的對象,如果使用new關鍵字重新創建對象,再賦值上相同的屬性,這樣做比較繁瑣而且也容易出錯,PHP提供了對象克隆功能,可以根據一個對象完全克隆出一個一模一樣的對象,而且克隆以後,兩個對象互不幹擾。
關鍵字:clone
$克隆對象名稱 = clone $原對象名稱;
克隆一個跟$原對象名稱一模一樣的一個對象。
__clone()
如果想在克隆後改變原對象的內容,需要在類中添加一個特殊的__clone()方法來重寫原本的屬性和方法。__clone()方法只會在對象唄克隆的時候自動調用。
☆☆
MySQLoi基本操作1
1、面向過程:
我們用mysqli_connect()函數建立一個連接。然後選擇數據庫,然後發送SQL指令,最後釋放資源。
2、面向對象:
new新建一個mysqli對象,傳入數據庫連接的相關參數就可以獲得一個mysqli對象。可以通過$mysqli->connect_errno判斷連接是否有誤。
MySQLoi基本操作2
查詢:
面向對象執行操作也有4中。分別為查詢、新增、更新、刪除。
//查詢:
$result = $link->query(‘select * from user‘);
//獲得結果集中行的數目:
$num_rows = $result->num_rows.‘<br/>‘;
<?php header("Content-Type:text/html; charset=utf-8"); //連接數據庫 $link = new mysqli(‘localhost‘,‘root‘,‘123qwe‘,‘test‘); //設置字符集 $link->set_charset(‘utf8‘); $sql = ‘select * from user‘; //返回一個結果集 $link_result = $link->query($sql); //取出結果集 $resulut = $link_result->fetch_assoc(); #$resulut = $link_result->fetch_row(); #$resulut = $link_result->fetch_array(); var_dump($resulut); //釋放結果集 $link_result->close(); //關閉資源 $link->close();
---------------------------------------------------------------------------------------------------------
哪幾種形式:
fetch_assoc()
查詢到的一條數據以關聯數組的形式返回
---------------------------------------------------------------------------------------------------------
fetch_row()
查詢到的一條數據以索引數組的形式返回
--------------------------------------------------------------------------------------------------------
fetch_array()
查詢到的一條數據以索引數組和關聯數組的混合形式返回
---------------------------------------------------------------------------------------------------------
魔術方法:__get
__get(string $name)
在讀取不可訪問的屬性的值時該函數會被調用。$name是屬性名。
class Demo { private $age= 18; public $name; //當你訪問不存在的或者權限不夠的時候 function __get($name){ if($this->name == ‘admin‘){ return $this->$name; }else{ return "數據出錯"; } } } $a = new Demo(); $a->name=‘admin‘; echo $a->age;
//此時__get()的參數$name為age
魔術方法:__set
__set(string $name,mixed $val)
設置不可訪問的值時會調用該方法
class Demo { private $age; public $name; //當你設置不存在的或者權限不夠的屬性時,自動調用該方法 //起到一層過濾作用,一種安全機制 function __set($name,$val){ if($this->name == ‘admin‘){ echo $this->$name=$val; }else{ echo "權限不夠"; } } } $a = new Demo(); $a->name = ‘admin‘; $a->age=18; //此時__set()的參數$name為age,$val為18
【編程開發】PHP---面向對象