PHP之面向對象三大特性

什麼是面向對象?

面向對象編程,也就是我們常說的OOP,其實是面向對象的一部分。面向對象一共有3個部分:面向對象分析(OOA)、面向對象設計(OOD)、面向對象編程(OOP)。我們現在將要學習的就是面向對象的編程,而面向對象編程中兩個首要了解的也是很重要的概念就是類和對象。

類與對象

對象:具有某種屬性和行爲的實體,例如人有姓名和年齡等屬性,具有工作、吃飯、睡覺等行爲。

類:具有相同特徵和功能的對象的抽象

面象對向的三大特點

封裝性、繼承性、多態性

首先簡單理解一下抽象:我們在前面定義一個類的時候,實際上就是把一類事物共有的屬性和行爲提取出來,形成一個物理模型(模版),這種研究問題的方法稱爲抽象

一、封裝性 

封裝就是把抽取出來的數據和對數據的操作封裝在一起,數據被保護在操作的內部,程序的其他部分只有被授權的操作(方法)才能對數據進行操作。 

php提供了三種訪問控制修飾符 

public 表示全局,本類內部,類外部,子類都可以訪問 

protected 表示受保護的,只有本類或子類可以訪問 

private 表示私有的,只有本類內部可以訪問 

以上三種修飾符既可以修飾方法也可以修飾屬性(變量),方法如果沒有訪問修飾符則默認是public,成員屬性必須指定訪問修飾符。

<?php

class Person{

    public $name;

    protected $age;

    private $salary;

    function __construct($name,$age,$salary){

        $this->name=$name;

        $this->age=$age;

        $this->salary=$salary;

    }

    public function showinfo(){

        echo $this->name."||".$this->age."||".$this->salary;

    }

}

 

二、繼承性 

子類自動繼承一個或多個父類中的屬性與方法,並可以重寫或者添加新的屬性或方法。這個特性簡化了類和對象的創建,提高了代碼的可重用性。

繼承就是一個子類(Subclass)通過 extends 父類 把父類(BaseClass)中的public 和 protected 的屬性和方法繼續下來,不能繼承private屬性和方法 

語法結構: 

class 父類名{} 

class 子類名 extends 父類名{}

細節: 

1、一個子類只能繼承一個父類(這裏指直接繼承);但是一個接口可以繼承多個接口

2、在創建某個子類對象時,默認情況下不會自動調用其父類的構造函數,除非子類中沒有構造函數

3、在子類中如果需要訪問父類的方法(構造方法、成員方法 方法的修飾符爲protected或private),那麼可以使用 父類::方法名 或者 parent::方法名 來完成【這裏parent和以前提到的self都均爲小寫,大寫報錯】

4、如果一個子類(派生類)的方法名與父類的方法名完全一樣時(public,protected),我們稱爲方法覆蓋或方法重寫(override)

三、多態性

多態(Polymorphism)按字面上意思理解就是“多種形狀”。可以理解爲多種表現形式,也即“一個對外接口,多個內部實現方法”。在面向對象的理論中,多態性的一般定義爲:同一個操作作用於不同的類的實例,將產生不同的執行結果。也即不同類的對象收到相同的消息時,將得到不同的結果。

PHP是一種弱類型語言(例如$i可以是任何類型的變量),不支持通過重載實現多態,但是PHP可以變向的實現多態效果

在實際的應用開發中,採用面向對象中的多態主要在於可以將不同的子類對象都當作一個父類來處理,並且可以屏蔽不同子類對象之間所存在的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。

在實際的應用開發中,通常爲了使項目能夠在以後的時間裏的輕鬆實現擴展與升級,需要通過繼承實現可複用模塊進行輕鬆升級。在進行可複用模塊設計時,就需要儘可能的減少使用流程控制語句。此時就可以採用多態實現該類設計。

多態的好處:大大提高程序的擴展,增強系統的靈活性,降低模塊間的耦合。

多態的應用:父類對象的引用指向子類對象,其實本質上就是一個向上轉型。

舉個模型例子,一家公司有員工類(Employee),還有其子類:銷售(Sales)、市場(Market)、工程師(Engineer)等。某一天老闆招待所有的員工開了個短會,完了之後對所有的員工(Employee)說,大家回去工作吧。在這裏我們可以認爲老闆調用了所有員工對象的continueToWork()方法,而不是對一個個員工細說做什麼工作,比如對銷售部說你去制定銷售計劃(調用makeSalePlan();),對市場部說你去制定產品的價格(調用makeProductPrice();)…這種逐個細說的方式並不是面向對象,而是面向個體。可以確定的是,員工類應該有一個方法continueToWork()。而員工如何實現他們工作的方法卻只有精確到子類才能確定,因爲不同的員工的工作方式是不一樣的。因此,我們很多時候只需要關心對象的父類型,而忽略更精確的子類型,比如上面老闆叫大家回去工作時,他對全體員工說的,主要指的是全體員工類型

實現實例:

 

<?php

abstract class Employee{

    abstract function continueToWork();

}

class Sales extends Employee{

    private function makeSalePlan(){

        echo "make sale plan";
    }



    public function continueToWork(){

        $this->makeSalePlan();
    }

}



class Market extends Employee{

    private function makeProductPrice(){

        echo "make product price";
    }


    public function continueToWork(){

        $this->makeProductPrice();

    }

}



class Engineer extends Employee{

    private function makeNewProduct(){

        echo "make new product";
    }



    public function continueToWork(){

        $this->makeNewProduct();

    }

}



class Demo{

//添加父類類型限制傳參類型,使其滿足多態第三點要求,父類指向子類

    public function Work(Employee $employeeObj){

        $employeeObj->continueToWork();

    }

}

//調用

$obj = new Demo();

$obj->Work(new Sales());//make sale plan

$obj->Work(new Market());//make product price

$obj->Work(new Engineer());make new product

參考:

https://blog.csdn.net/whd526/article/details/70242918

https://www.jb51.net/article/30248.htm

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章