面向過程 :每個小系統有着明確的開始和和結束 。開始和結束之間有着嚴謹的因果關系。
比如 :上帝創造一個人,如果有70億人那就很麻煩
隨機函數先獲取隨機的數字 作為數組的下標,然后再從數組中獲取對應下標的數字。
面向對象
引入例子 :女媧 人身蛇尾 , 用女媧造人引出類和實例 : 女媧造人前先 思考 人的形象 然后再造人
所以 :人的形象是抽象的,用來說明人的特點;而每一個人都是具體的,且符合人的形象
類 :所有對象共同點的一個抽象!(就是一個 制造說明書)
對象 :就是根據說明書制造出來的具體對象
類中有什么? 屬性(比如人:身高,體重,姓名)
能干什么?功能(說活,吃飯)
用 變量 和 函數 分別模擬 屬性 和 功能
面向對象中 ,方法即是函數 ; 屬性即是變量 ,只是面相對象中一般說方法和屬性
new 類名();//直接產生一個對象並返回該對象
$a = new 類名(); //那么a對象就包含 類中聲明的所有屬性(類似關聯數組)
要調用對應的屬性值可以 $a -> name (name不用$);要調用對應的方法 $a -> say()
面向對象oo(object oriented)oop加編程
聲明類的時候 :
內存分配給類一個空間,,里面存放着類定義的屬性和函數
new對象的時候 :
1、 申請內存,生成對象(屬性集合)
2、 如果有構造函執行
3、 返回對象的地址
內存分配圖
語法就是法律; 規范 就是 道德
(1)屬性的初始化 不能是表達式 如 : $a = 1+3 ; java中是允許的
(2)同一個域內(比如一個類中),函數不能重復定義(即是名字不能一樣)
(3)在一個類里面,如果要調用系統同名的自定義函數,需要用$this,否則調用系統函數 ; 此外一個類里面 一個函數調用 不是他內部的變量或者它調用其他函數也要加 $this
構造函數 : __construct() , 注意前面是兩個下划線 ; 當new對象(產生對象),調用 ; 構造函數不能被重載即是不能再有同名的
析構函數 :__destruct()在對象被銷毀的時候調用的函數 。
如何銷毀對象 :
1、顯式銷毀,unset(),直接賦值為null或者其他值
2、執行完最后一行代碼時自動銷毀(如果之前已經銷毀,則不再銷毀)
對變量指向銷毀問題
$a = new People(); //創建一個對象(new People()),並把使用權給變量$a($a是一個變量名,指向這個對象)
$a = $b = $c ; //3個變量都指向內存中的同一個對象
unset($a);//unset,即是銷毀對象(object),但有其他變量$b等仍然指向對象,那么該對象將不能被銷毀,但是$a為null不再指向這個對象
this綁定
當一個對象調用一個它對應類的方法時,該方法執行之前先完成一個綁定,即是用
$this綁定到調用此方法的對象(這樣才能在方法內對這個對象的屬性進行操縱),因為方法內如果想訪問調用者(即是對象)的屬性必須用$this;否則則理解為方法內部的一個局部變量
Java中不一樣,函數不需要this也能訪問方法外的變量
封裝
封裝的概念 : 通過修飾符 改變屬性或者函數的訪問權限 ,達到保護的作用。
光是封裝起來是沒意義的,還要供外部交互才行;所以通過一個開放的接口(即是一個函數)供外部操縱;內部的操作,不需要外部知道,從而隱藏內部的一些細節 。
如: 洗衣機,你只要點擊啟動程序的按鈕就能洗衣服,不需要知道洗衣機內部怎么運行
權限修飾符 :private protected public
private修飾的屬性只能在其 類里面 才能被訪問到。
protected 本類和子類能訪問
private訪問權限的bug : 對象之間能夠相互操作同一個類中的屬性,導致一個對象能夠修改另一個對象的屬性。
fatal error(致命錯誤)
封裝 操作數據庫的 類
類似把某個功能的一段代碼放在一個類中 ; 類里面的方法相互調用
用面向對象的思想 對數據庫操作 (mysql封裝類)
比如把連接數據的操作封裝到一個連接函數中
連接數據庫
發送 查詢
對於select語句 返回查詢數據數據
關閉mysql連接
繼承
子類繼承父類的屬性和方法,再進一步拓展自己的屬性和方法;父類的屬性 和方法一般是一個歸納(所有對象都有的),提高代碼的重新性
擁有問題 :子類繼承父類,子類有父類所有的屬性和方法,在子類里面能夠操作父類中非private修飾的屬性或者方法,但是父類中對於private修飾的屬性或者方法子類無法操作(類外的范圍限制)
調用與覆蓋問題 : 子類里面調用對應的屬性時,子類沒有覆蓋父類中的屬性或者方法,則調用父類中的屬性或方法,否則只調用子類中的,無論傳參數是否對。private的調用除外
注意繼承父類之后,子類再聲明與父類一樣的屬性,權限符只能越來越寬松或者一樣 。 如果父類的屬性有static,子類也必須有才能聲明
★類內一般聲明只屬性和方法,實例化或者輸出等語句要寫在方法里或者類外,否則報錯
如果子類有和父類一樣的方法,能使用parent::方法名()指定調用父類的
構造函數是可以被繼承的;如果子類中沒有寫構造函數,在實例化子類的時候就會調用父類的構造方法。如果子類重新寫則覆蓋且只調用子類的。
因此如果父類的構造函數是必須要調用,最好使用parent::__construct()調用一下(java不同,它會先調用父構造再調用子構造;php調用子構造)
比如 :數據庫類中 父類構造函數有連接數據庫,如果子類寫了其他的話構造函數,則連接失敗 (Java不同,父子都調用)
在類外對象名只能調用類中public修飾的屬性,其他的屬性可以通過方法來調用。一般不寫則默認為public
多態
只抽象聲明父類,具體的工作由子類對象完成
java出現多態是因為它是強類型語言(即是定義了類型不能隨便改變),聲明的類型 后 傳送參數必須是該類型 。 聲明參數時,聲明為父類型,傳參時,能夠傳子類型。以達到多態的效果。比如:
多顏色手電筒問題 :聲明手電筒,並接受玻璃的參數。然后玻璃有多種顏色,以達到不同效果。則為多態
php是弱類型語言,本身沒有對類型沒有檢測,因此簡直變態,后來5.3以后,引入了對於對象類型的參數檢測。限制了靈活性達到多態
static 靜態屬性
一般當 某個屬性或者方法 是所有對象固有的(即是不改變),則聲明為靜態屬性,節省內存,隨時類名調用;無論函數調用多少次,只初始化第一次.,如 static $a = 1;
靜態屬性存在於類內存中,而不是對象的內存中。只要有類就能訪問到,因此一個靜態屬性只有一個,改1全變;只能 類名::屬性名 訪問
靜態方法
普通方法和靜態方法都存在 類內存 中 且只有一個
但是靜態方法用類名調用,不用this綁定;普通方法需要有對象才能用this綁定調用
安裝ecshop的時候出現strict standard錯誤提示,原因是版本高,代碼書寫語法有誤,靜態方法調用非靜態方法時出現問題。
非靜態方法,是不能由類名靜態調用的.但是 PHP中的面向對象檢測的並不嚴格,
只要該方法沒有$this,就會轉化靜態方法來調用.
但是,在PHP5.3的strict級別下,或者PHP5.4的默認級別
都已經對類名::非靜態方法做了提示
則會提示:Strict Standards: Non-static method Human::eat() should not be called statically
不能靜態的去調用非靜態方法 ; 有static修飾的變量和函數不能出現$this
isset($this) 這個時候判斷有沒對象進行綁定;
代碼分析
this就是指向當前對象實例的指針,不指向任何其他對象或類
self, parent的用法 (::(域運算符號))
self:指向類本身,也就是self是不指向任何已經實例化的對象 ,self使用來指向類中的靜態屬性或者方法
self::$staticProperty
self::staticMothed;
parent: 指向父類的指針,一般我們使用parent來調用父類的構造函數。
在引入自身的靜態屬性/靜態方法,以及父類的方法時,可以用到.
parent::$staticProperty
parent::Mothed;
★應該選擇this還是parent
總結使用
1: 修飾類的屬性與方法為靜態屬性,靜態方法
2: static::method(), 延遲綁定
3: 在函數/方法中,聲明靜態變量用