PHP之面向對象(上)


面向過程 :每個小系統有着明確的開始和和結束 。開始和結束之間有着嚴謹的因果關系。

比如 :上帝創造一個人,如果有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: 在函數/方法中,聲明靜態變量用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM