綜合學習---面向物件2
阿新 • • 發佈:2018-12-14
/***************************************************************************/ /*******************************【面向物件】****************************/ 面向物件(OOP)---Object Oriented Programming 概念:以面向物件思想為指導的一種程式設計方式。 [附加說明] 它將物件作為程式的基本單元,將程式和資料封裝其中,提高了軟體的重用性、靈活性和可擴充套件性。 【面向過程的侷限性】 1、程式碼冗餘率高,重用性低。 2、中途需求發生改變,程式碼的改動量將會相當龐大。 【建立物件的原理】 1、每一次例項化出一個新的物件,都會在記憶體中開闢一個新的記憶體空間。 2、通過物件操作成員屬性和方法其實是操作自己記憶體空間中的成員屬性和成員方法。 /* 物件的比較 */ <?php class Test { public function demo() { echo "string"; } } $obj = new Test(); $obj2 = new Test(); var_dump($obj == $obj2); //bool(true) var_dump($obj ===$obj2); //bool(false) ?> [分析] 如果使用"=="作比較,比較的只是記憶體空間中的內容; 如果使用"==="比較,不同的空間也會進行比較。 /************************************************************************/ /***************************【靜態/棧/堆記憶體分配】***********************/ [參考]http://blog.csdn.net/hushpe/article/details/45396059 { [靜態儲存區] 記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。它主要存放靜態資料、全域性資料和常量。 [棧區] 在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高, 但是分配的記憶體容量有限。 [堆區] 亦稱動態記憶體分配。程式在執行的時候用malloc或new申請任意大小的記憶體,程式設計師自己負責在適當的時候用free或delete釋放記憶體。動態記憶體的生存期可以由我們 決定,如果我們不釋放記憶體,程式將在最後才釋放掉動態記憶體。但是,良好的程式設計習慣是:如果某動態記憶體不再使用,需要將其釋放掉,否則,我們認為發生了記憶體洩漏現象。 總之,對於堆區、棧區和靜態儲存區它們之間最大的不同在於,棧的生命週期很短暫。但是堆區和靜態儲存區的生命週期相當於與程式的生命同時存在(如果您不在程式 執行中間將堆記憶體delete的話),我們將這種變數或資料稱為全域性變數或資料。但是,對於堆區的記憶體空間使用更加靈活,因為它允許你在不需要它的時候,隨時將它釋 放掉,而靜態儲存區將一直存在於程式的整個生命週期中。 } /************************************************************************/ /***************************【類的繼承】*********************************/ [解決問題] 減少程式碼的重複定義,提高程式碼的重用性。 (只能繼承父類中非私有成員) [執行過程] 本類中查詢 屬性,找不到 沿著繼承鏈 去父類中查詢 [分類] 單繼承 { 從一個基類派生的繼承稱為單繼承。 [特性] 在單繼承中,每個類可以有多個派生類,但是每個派生類只能有一個基類,從而形成樹形結構。 } 多繼承 { 從多個基類派生的繼承稱為多繼承。 [特性] 一個子類可以有多個父類,它繼承了多個父類的特性。它的派生類具有多個基類,派生類與每個基類之間的關係仍可看作是一個單繼承。 } 說明:基類--->父類; 派生類--->子類 【附加說明】 PHP中類繼承只能單繼承,不能多繼承(但是可以通過介面實現多繼承) 一個類可以實現多個interface(繼承介面),這彌補了類的多繼承問題。 /************************************************************************/ /***************************【類的重寫】*********************************/ [解決問題] 有時候,在子類中,我們需要對父類中已有的一些方法進行改進。 [定義] 所謂重寫,就是對父類中已有的方法進行重新定義。 /************************************************************************/ /***************************【訪問限定修飾符】***************************/ [解決問題] 用來限定 成員屬性 和成員方法 [型別] Public 表示公共的型別 Protected 表示受保護的型別 Private 表示私有的型別 [限定範圍] public 類內 子類 類外 protected 類內 子類 private 類內 [許可權修飾符] ---- "::"這個符號叫範圍解析操作符。 /************************************************************************/ /***************************【Final類/方法】***************************/ /* Final類 */ [解決問題] 通過關鍵字Final宣告一個類,這個類將不能被繼承,也就意味著類中的所有成員方法將不能被重寫 /* Final方法 */ [解決問題] 控制本方法不可被重寫 [注意] 1、雖然我們將某個類的方法進行final申明瞭,但是這個方法所在的類依然能夠被繼承,並且呼叫使用;final只是限制這個方法不能被重寫(重寫是會報錯)。 2、屬性不能被定義為 final,只有類和方法才能被定義為 final。 AG: { <?php class Demo { final test() { echo "string"; } } class Demo1 extends Demo { // !錯誤----final方法可繼承,不可重寫 // final test() // { // echo "重寫final方法"; // } } ?> } /************************************************************************/ /***************************【抽象類】**********************************/ /*****************************************************************************/ /***************************【靜態延時繫結】**********************************/ 靜態延時繫結是PHP5.3版本之後的改進特性。 /* 特點 */ 第一點靜態,也就是說這個功能只適用於靜態屬性或靜態方法。 第二點延遲繫結 /* 解決了什麼問題 */ 在編譯的時候,無法確定到底是哪個子類呼叫該方法(或屬性) (因為可以有無限多個子類可以繼承該類);只有在程式執行的時候 確定究竟是哪個子類呼叫到了他,static才能繫結哪個子類的類名。 /* 使用場景 */ 比如一個會員父類 class Vip 下面兩個子類分別是 超級會員 svip 和 年費會員 yvip 可以在兩個子類中分別重寫 static usergroup() 方法 或者其他靜態屬性 ,父類中使用延遲靜態繫結 這樣可以寫出很優雅的程式碼 /* 使用案例 */ <?php class A{ static $name = "Tom"; public function printName(){ echo static::$name."\n"; static::fun(); /* 區別主要在這裡,使用self/static,static具有延時特性 */ // echo self::$name."\n"; // self::fun(); } static function fun(){ echo "A Class\n"; } } class B extends A{ static $name = "Jon"; static function fun(){ echo "B Class\n"; } } $obj = new B(); $obj->printName(); // 輸出結果 // Jon // B Class ?> /*****************************************************************************/ /********************************【PHP過載】**********************************/