PHP面向對象編程高級

一、OOP(Object-Oriented Programming )概述

面向對象的編程特色:代碼更簡潔、更易於維護,而且具備更強的可重用性。
軟件工程的三個目標:重用性、靈活性、擴展性
面向對象編程三大特性:封裝、繼承、多態(PHP不支持)php

二、封裝

封裝是從對象抽象成類的過程,其將數據和數據的操做捆綁在一塊兒,造成對外界的隱蔽,同時對外提供能夠操做的接口編程

三、繼承

繼承是類的細分過程,是代碼複用的一大手段數組

繼承的基礎:子類(要繼承其餘類的類,派生類)和父類(被繼承的類,基類)之間是一種被包含和包含的關係,相似人類(對應子類)和動物類(對應父類)的關係php7

繼承關鍵字:extendside

class Human{}
class Man extends Human{}

繼承的效果:父類中大多數屬性和方法在子類中能夠直接訪問函數

有限繼承:子類能夠繼承父類除私有方法以外的全部成員測試

在PHP中一個類只能繼承一個父類,想繼承多個類能夠嘗試使用鏈式繼承this

四、成員重寫Override

子類中定義了與父類重名的成員的行爲稱爲重寫,重寫後,子類直接訪問重寫後的成員,若是須要訪問父類中重寫前的成員(只包括靜態屬性、靜態方法、類常量和普通方法),能夠在子類中使用parent關鍵字表明父類進行訪問parent::成員名稱spa

重寫方法原則:.net

a.控制權不能高於父類

b.參數個數和數據類型(php7)必須一致,形參名字能夠更改

c.私有方法不能被繼承,故不受重寫規則限制

五、靜態成員綁定

利用static代替靜態綁定self,使用靜態成員的重寫,使得在類內部用來表明自己的關鍵字不是在類編譯時固定好,而是當方法被訪問是動態地選擇來訪者所屬的類

class Human{
    public static $name = 'Human';

    public static function getName(){
        echo self::$name,':self:<br>';
        echo static::$name,':static:<br>';
    }
}
class Man extends Human{
    public static $name = 'Man';
}
Man::getName();
/*
 *結果
 *Human:self:
 *Man:static:
 */

靜態延遲綁定只有在繼承時纔有意義,它是根據調用類的不一樣而選擇不一樣的表現

六、繼承終結者:Final關鍵字解說

final關鍵字只能修飾類和方法,不能用來修飾屬性和類常量

最終類:使用final關鍵字修飾的類即爲最終類:final class ClassName{},最終類沒法被繼承

final修飾方法時,該方法能被繼承但不能重寫

七、抽象類和抽象方法:Abstract關鍵字解說

使用abstract修飾的類和方法稱爲抽象類和抽象方法

抽象類不能實例化,只能被繼承,

抽象方法只能存在於抽象類或接口中,抽象方法不能有方法體,

繼承抽象類的非抽象子類必須實現抽象類中的全部抽象方法,故抽象方法不能使用private修飾

//定義抽象類
abstract class Human{
    //聲明抽象方法
    abstract function display();
    //聲明普通方法
    function fn(){
        echo __MATHOD__.'<br>';
    }
}

class Man extends Human{
    //重寫抽象方法
    function display(){
        echo 'Man';
    }
    //普通方法沒必要重寫
}

八、接口Interface

接口是相似類的一種結構,使用interface來聲明:interface InterfaceName{}

接口不能被實例化,只能被類實現,使用implements關鍵字:class ClassName implements InterfaceName{}

接口成員:只能定義抽象方法和接口常量

//聲明接口
interface Human{
    //定義接口常量
    const Name = '人';
    //定義抽象方法,默認是抽象方法,不能使用abstract關鍵字修飾
    public function eat();
}
//實現接口
class Man implements Human{
    //實現抽象方法
    public function eat(){
        echo '男人在吃東西<br>';
    }
}

抽象類實現接口時沒必要實現抽象方法

接口的抽象方法必須使用public修飾

實現接口的類不容許重寫接口常量,不容許增長方法控制權限,接口能夠多繼承接口,依然是使用extends關鍵字

interface Ship{}
interface Aerocraft{}
interface Airship extends Ship,Aerocraft{}

九、解決單繼承問題的代碼複用機制trait

trait也是一種相似class的關鍵字:trait TraitName{}

trait中能夠擁有類中除常量外的其餘全部成員,包括抽象方法,trait不能被實例化和繼承

在類中使用trait代碼須要使用use關鍵字:class ClassName{ use TraitName;}

在類中use了具體類時,至關於trait中的代碼在類中寫了一遍。

一個類中可使用多個trait

trait t1{
    function f1(){
        echo "string";
    }
}
trait t2{
    function f2(){}
}
class C{
    use t1,t2;
    function f3(){
        $this->f1();
        $this->f2();
    }
}

使用的多個trait中成員重名時

trait t1{
    function f1(){
        echo "string";
    }
}
trait t2{
    function f1(){}
}
class C{
    use t1,t2{
        t2::f1 insteadof t1;    //表示f1引用的t2中的f1
        t2::f1 as f2;            //重命名t2中的f1爲f2,不寫這句則t2::f1沒法被使用
    }
    function f3(){
        $this->f1();
        $this->f2();
    }
}

類中不容許屬性和trait中的屬性同名,方法同名時,類中的方法會覆蓋trait中的同名方法,trait中的方法會覆蓋繼承來的同名方法。

容許類使用別名的方式放鬆方法訪問控制權

trait t1{
    private function f1(){
        echo "string";
    }
}
class C{
    use t1{
        f1 as public f2;
    }
}
$c = new C();
$c->f2();

十、魔術方法

PHP所提供的"重載"(overloading)是指動態地"建立"類屬性和方法,是經過魔術方法來實現的。
當調用當前環境下未定義或不可見的類屬性或方法時,重載方法會被調用。(屏蔽錯誤)
全部的重載方法都必須被聲明爲 public。
屬性重載只能在對象中進行。在靜態方式中,這些魔術方法將不會被調用。因此這些方法都不能被 聲明爲 static。
這些魔術方法的參數都不能經過引用傳遞。
---------------------

php重載的內容引用了:
做者:和尚周
來源:CSDN
原文:https://blog.csdn.net/csdn_heshangzhou/article/details/80990687

__construct  構造方法
__destruct  析構方法

__clone 克隆方法

__toString

實現該函數可在echo一個對象時顯示一個提示  function __toString(){   return $tipstrmsg;}

__call
實現該方法後調用類中不存在的方法時,顯示調用不存在信息   function __call($i,$j){ //$i接收方法名,$j接收參數數組}

__callStatic()
描述:用靜態方式中調用一個不可訪問方法時,__callStatic() 會被調用。public static function __callStatic ( string $name , array $arguments )

__get
訪問類中無權訪問的成員時調用該方法提示信息  function __get($i){ //$i訪問的成員}

__set
設置類中無權設置的成員時調用該方法提示信息  function __set($i,$j){ //$i要設置的成員,$j要設置的值}

__isset
查看類中無權查看的成員  function __isset($i){echo "您無權查看{$i}是否存在!";}

__unset
刪除類中無權刪除的成員  function __unset($i){echo "您無權刪除{$i}!";}

測試代碼:

class ClassName{
    private $a = 1;
    private function pri(){}
    public static function s(){}

    public function __get($var){
        echo "<br>Error:屬性{$var}沒法訪問!<br>";
    }

    public function __set($var,$value){
        echo "<br>Error:無權設置屬性{$var}的值!<br>";
    }

    public function __isset($var){
        echo "<br>Error:您無權查看{$var}是否存在!<br>";
    }

    public function __unset($var){
        echo "<br>Error:您無權刪除{$var}!<br>";
    }

    public function __call($func,$args){
        echo "<br>Error:方法{__MATHOD__}不可訪問!<br>";
    }

    public static function __callStatic($func,$args){
        echo "<br>Error:靜態方法{__MATHOD__}不可訪問!<br>";
    }

    public function __toString(){
        return 'object('.__CLASS__.')';
    }
}

$c = new ClassName();
echo $c->a;
$c->a = 3;
isset($c->a);
unset($c->a);
$c->pri();
$c->s();
echo $c;

測試結果:

相關文章
相關標籤/搜索