PHP類方法重寫原則

可能咱們平常工做中不多用到這塊知識點,但我仍是喜歡把遇到的卻不清楚的知識點摸清php

PHP的類方法重寫規則ide

一、final修飾的類方法不可被子類重寫

final修飾的類方法不可被子類重寫 即使final private方法沒法被繼承 子類仍不能對齊進行重寫函數

class FinalMethod
{
    //可繼承不可重寫
    final public function finalPublic()
    {
        echo "can be inherited, but be overrided";
    }
    //可繼承不可重寫
    final protected function finalProtected()
    {
        echo "can be inherited, but be overrided";
    }
    //不可繼承不可重寫 雖然子類繼承不到父類的private方法 但同時也會被final限制沒法重寫
    final private function finalPrivate()
    {
        echo "can not be inherited or be overrided";
    }
    //雖然不可繼承 但子類裏可重寫此方法
    private function private()
    {
        echo "can not be inherited ,but be overrided";
    }
}

class Override extends FinalMethod
{
    //error
    public function finalPublic()
    { 
    }
    //error
    protected function finalProtected()
    {
    }
    //error
    private function finalPrivate()
    {
    }
    //correct
    public/protected/private function private()
    {
        //子類繼承父類重寫父類方法時訪問級別只能更加寬鬆 不可更爲嚴格
    }
}
二、PHP是否重寫父類方法只會根據方法名是否一致判斷(5.3之後重寫父類方法參數個數必須一致)

這裏並非說方法參數無任何做用 PHP無重載機制 因此判斷是否是重寫只會經過方法名(C/C++不只要方法名相同,參數也相同時才被視爲重寫,不然即爲重載,即新定義了一個多態函數的態) 當方法名相同時即被認爲是在重寫父類方法,5.2能夠參數不一樣,5.3之後參數需和父類方法一致,且都追尋繼承訪問級別的規則。spa

class Father
{
    public function index($args_1)
    {
    }
}

class Child extends Father
{
    //5.3之後重寫方法必須與父類保持參數個數相同
    public function index($args_1, $args_2)
    {
        //在C/C++中此爲重載非重寫,由於C/C++具備標準的多態機制,會因參數不一樣而視爲某一方法的另外一種態
        //but在php中此依然爲重寫 但5.3之後此爲非法 必須與父類的方法參數個數保持一致
    }
    //5.3之後重寫方法必須與父類保持參數個數相同
    private function index($args_1, $args_2)
    {
        //C/C++會由於參數不一樣於父類方法而視爲重載,即新定義了一個函數的態,因此不會受到繼承訪問權限的限制
        //但php仍然會被視爲對父類方法的重寫,會受到繼承訪問權限的升降規則限制
    }
}
三、重寫時訪問級別只能夠等於或者寬鬆於父類 不可提高訪問級別

父類的public方法不能被子類重寫爲protected或者private,protected方法不能被重寫爲private,能夠寬鬆er,不能夠嚴格ercode

class Father
{
    public function index()
    {
    }
}

class Child extends Father
{
    protected/private function index()
    {
       //訪問權限提高 錯誤 
       //父類爲public 則子類重寫也只能爲public
       //父類爲protected 則子類可爲public/protected
       //父類爲private 則子類public/protected/private皆可
    }
}

其實關於訪問級別繼承規則有不少有趣的地方orm

private在咱們常識中是沒法被繼承的,子類拿不到,但其訪問級別已經是最高,因此你在子類中能夠寫成private protected public 彷彿是咱們本身從新定義了一個函數同樣,這點在5.2版本以前尤爲突出,由於5.2以前的版本在繼承重寫父類方法是能夠不保持參數個數相同,但5.3之後增強了這方面的限制,參數個數必須與父類相同繼承

注:接口

    子類實現父類的抽象方法或某類實現接口的方法時其實仍屬於繼承關係,仍追尋訪問等級只能下降不可提高的規則
it

    並且io

           抽象方法不可被聲明爲private,abstract修飾的方法確定是用於繼承實現的,因此只能是public或者protected

           接口的方法聲明必須爲public,interface裏聲明的方法也確定是被繼承實現的,且只能是public,                                       implements               此接口的類也指定重寫成public類型的方法

相關文章
相關標籤/搜索