PHP的面向對象 — 封裝、繼承、多態


      K在上一次的基礎篇中給大家介紹了一下關於PHP中數組和字符串的使用方法等,這一次,K決定一次性大放送,給大家分享一下PHP中面向對象的三大特性:封裝、繼承、多態三個方面的知識。

一、封裝

  在PHP中,封裝可以用三個子來概括:私有化。具體來說,是通過訪問修飾符,將類中不需要外部訪問的屬性和方法進行私有化處理,來實現訪問控制。

  那么封裝的作用是什么?封裝的作用主要有兩點,一是方法封裝,即將使用者關注的功能暴露,而隱藏其他使用者用不到的功能;二是屬性封裝,即對用戶的數據進行控制,防止不合法的數據傳輸設置。

  那么封裝操作是如何實現的?

  對於方法的封裝,我們通過對方法前加private關鍵字來進行設置,即進行私有化處理。demo如下:

private function formatName(){} // 這個方法僅僅能在類內部使用$this調用
         function showName(){
             $this -> formatName();
         }

  對於屬性的封裝,我們可以有兩種方法來進行實現。

  一是通過自己提供的set/get方法來對私有化的屬性進行設置/讀取。demo如下:

private $age;
         function setAge($age){
             $this -> age = $age;
         }
         function getAge(){
             return $this -> age;
         }

  二是通過魔術方法來進行實現。demo如下:

private $age;
function __get($key){
    return $this -> $key;
}
function __set($key,$value){
    $this -> $key = $value;
}
$對象 -> age;  >>> 訪問對象私有屬性時,自動調用__get()魔術方法,並且將訪問的屬性名傳給__get()方法;
$對象 -> age = "11";  >>> 設置對象的私有屬性時,自動調用__set()魔術方法,並且將設置的屬性名以及屬性值傳給__set()方法;

  此外,有關封裝的魔術方法主要有以下幾種:

   ① __set():給類私有屬性賦值時自動調用,調用時給對象傳遞兩個參數,需要設置的屬性名、屬性值
   ② __get():讀取類私有屬性時自動調用,調用時給方法傳遞一個參數,需要讀取的屬性名
   ③ __isset():外部使用isset()函數檢測私有屬性時,自動調用。
   >>>類外部使用isset()檢測私有屬性,默認是檢測不到的。即false
   >>>所以,我們可以使用__isset()函數,在自動調用時,返回內部檢測結果。
   function __isset($key){
     return isset($this->$key);
   }
   當外部使用isset($對象名->私有屬性)檢測時,將自動調用上述__isset()返回的結果!
   ④ __unset():外部使用unset()函數刪除私有屬性時,自動調用。
   function __unset($key){
    unset($this->$key);
   }
   當外部使用unset($對象名->私有屬性)刪除屬性時,自動將屬性名傳給__unset(),並交由這個魔術方法處理。

二、繼承

  在PHP中,繼承也可以用單詞extends來概括。extends在子類上使用,可以讓子類繼承父類中的非私有屬性和方法。demo如下:

class Student extends Person{}

  但是,在使用繼承時,需要注意以下幾點:

  ① 子類只能繼承父類的非私有屬性。
  ② 子類繼承父類后,相當於將父類的屬性和方法copy到子類,可以直接使用$this調用。
  ③ PHP只能單繼承,不支持一個類繼承多個類,但是一個類可以進行多層繼承。
   >>> class Person{}
   class Chengnian extends Person{}
   class Student extends Chengnian{}
  Student類就同時具有了Chengnian類和Person類的屬性和方法

  下面給大家介紹一下關於方法重寫(方法覆蓋)的一些知識。

  方法覆蓋是指子類對繼承父類中重名方法的重寫或覆蓋,而它的實現需要滿足兩個條件,一是子類繼承父類;二是子類重寫父類已有方法。

  那么如果我想要在調用父類中的方法,應該怎么做?我們可以通過如下代碼實現:

parent::方法名();

  同理,在子類繼承父類時,首先也要調用父類的構造函數來賦值,實現代碼如下:

function __construct($name,$age,$school){
    parent::__construct($name,$age);
    $this -> school = $school;
}
// 其中name、age屬性繼承自父類,school屬於子類

三、多態

  在PHP中,多態是最常用到的一種特性。所謂多態,是指同一個東西不同形態的展示。在PHP中,我們這樣定義多態,一個類被多個子類繼承,如果這個類的某個方法在多個子類中表現不同的功能,那么這種行為我們就稱其為多態的實現。

  多態的實現必須要滿足三個條件:一是子類繼承父類,二是子類重寫父類的方法,三是父類引用指向子類對象

  多態的實現K用一個小小的demo來給大家進行演示,demo如下:

    abstract class Person{
        abstract function say();
    }
    
    class Chinese extends Person{ // 條件一:子類繼承父類
        function say(){ // 條件二:子類重寫父類方法
            echo "我說中文!<br>";
        }
    }
    class English extends Person{ //條件一:子類繼承父類
        function say(){ // 條件二:子類重寫父類方法
            echo "I speak English!<br>";            
        }
    }
    
//    Person $c = new Chinese(); // 父類引用指向子類對象,PHP中此形式行不通
//    Person $e = new English();
    
    function func(Person $p){ //PHP中的類型約束只存在與函數的形參
        $p -> say();
    }
    func(new Chinese()); // 條件三:父類引用指向子類對象
    func(new English()); // 條件三:父類引用指向子類對象

 

好了,以上就是K給大家帶來的關於PHP面向對象中封裝、繼承、多態這三個特性的初步理解,如果對你有幫助的話,可不要忘了給K點個贊喲~

 


免責聲明!

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



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