PHP面向對象詳解:繼承、封裝與多態


首先,在解釋面向對象之前先解釋下什么是面向對象?

[面向對象]
1、什么是類?
 具有相同屬性(特征)和方法(行為)的一系列個體的集合,類是一個抽象的概念
2、什么是對象?
從類中拿到的具有具體屬性值得個體,稱為對象,對象是一個具體的個體

所以,面向對象即我們專注對象來處理問題,通過從一個個具有屬性和功能的類中拿到對象來處理問題。

下面我們再來細說下面向對象的三大特征:繼承/封裝/多態

一、繼承

在PHP中我們主要通關Extends關鍵字來實現繼承   ->class Student extends Person{}

下面是幾個比較重要的注意事項:

①子類只能繼承父類的非私有屬性。
②子類繼承父類后,相當於將父類的屬性和方法copy到子類,可以直接使用$this調用該屬性;
③PHP只能單繼承,不支持一個類繼承多個類。但是一個類可以進行多層繼承(即A繼承於B,而C又繼承於A,C通過A間接繼承了B)

二、封裝

類實現封裝是為了不讓外面的類隨意的修改一個類的成員變量,所以在定義一個類的成員的時候,我們使用private關鍵字設置這個成員的訪問權限

只能被這個類的其他成員方法調用,而不能被其他類中的方法調用,即通過本類中提供的方法來訪問本類中的私有屬性。

①所以在該類中我們會提供一個訪問私有屬性的方法

②然后我們一般會定義兩個方法來實現對一個變量的操作,即:get()set()方法。

代碼示例如下:

class Person{
        private $name;
        private $age;
        
        public function __construct($name,$age){
            $this->name = $name;
            $this->age = $age;
        }
        function setAge($age){
            if($age>=0&&$age<=120){
                $this->age = $age;
            }else{
                error_log("年齡設置有誤!");
            }
        }
        
        function getAge(){
            return $this->age;
        }
        public function say(){
            echo "我叫{$this->name},我今年{$this->age}歲了";
        }
        
        function __get($name){
            switch ($name) {
                case 'name':
                    return $this ->$name."這是讀取時加的文字";                    
                case 'age':
                    return "0".$this ->$name;
                default:
                    return $this ->$name;                    
            }
            
        }
        function __set($key,$value){
            
            if($key=="name"){
                $this->$key = $value."這是設置時加的文字<br>";
            }else{
                $this->$key = $value;
            }
        }
        function __isset($name){
            return isset($this->$name);
        }
        
        function __unset($name){
            if($name=="age"){
                return;
            }
             unset($this->$name);
        }
    }
 
$zhangsan = new Person("zhangsan",14);
$zhangsan->setAge(12);
echo $zhangsan->getAge()."<br>";
var_dump(isset($zhangsan->name));
unset($zhangsan->age);
echo $zhangsan->age;

三、多態

什么是多態?

一個類,被多個子類繼承,如果這個類的某個方法,在多個子類中,表現出不同的功能,我們稱這種行為為多態。(同一個類的不同子類表現出不同的形態)

那么我們如何來實現多態呢?

子類繼承父類 ->子類重寫父類方法 ->父類引用指向子類對象

abstract class Person{        注:父類使用abstract關鍵字修飾
abstract function say();
}

class Chinese extends Person{    注:子類重寫父類方法
function say(){
echo "我是中國人<br>";
}
}
class English extends Person{    注:子類重寫父類方法
function say(){
echo "我是英國人";
}
}

$zhangsan = new Chinese();
$zhangsan->say();
$z = new English();
$z->say();
Person $p = new Chinese();   注:父類引用指向子類對象

上述代碼中,兩個子類都是繼承自同一父類,但因為都重寫了父類的方法,表現出了不同的形態

 

 

* 四、單例設計模式


單例模式也叫單態模式
可以保證一個類只能有一個對象實例
實現要點:
①構造函數私有化,不允許使用new關鍵字創建對象。
②對外提供獲取對象的方法,在方法中判斷對象是否為空,如果為空則創建對象並返回,如果不為空則直接返回
③實例對象的屬性以及獲取對象的方法必須都是靜態的。
④之后,創建對象只能使用我們提供的靜態方法。

示例代碼如下:

class Singleton{
static public $Single = null;
private function __construct(){}
static function getSingle(){
if(!self::$Single){
self::$Single = new Singleton();//self代指類名 new Singleton()和newself()是完全一樣的
}

return self::$Single;
}

function __destruct(){
echo "我被銷毀了<br>";
}
} 
$s1 = Singleton::getSingle();
$s1 = Singleton::getSingle();
$s1 = Singleton::getSingle();

 


免責聲明!

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



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