2017-02-24 87 views
2

一位用戶發佈了對PHP Visibility manual page的評論。這是第二大投票評論。他使用此代碼示例:子類訪問父類的私有方法?

<?php 
abstract class base { 
    public function inherited() { 
     $this->overridden(); 
    } 
    private function overridden() { 
     echo 'base'; 
    } 
} 

class child extends base { 
    private function overridden() { 
     echo 'child'; 
    } 
} 

$test = new child(); 
$test->inherited(); 
?> 

輸出將是「基礎」。

據我所知:「子」類繼承了繼承的()方法。不會繼承覆蓋的()方法,因爲它是私有的,但是定義了它自己的方法。但是當測試對象(子類的實例)運行inherited()方法時,它會輸出「base」。

所以我的問題是:

  1. 爲什麼孩子跑到它不能訪問的方法?
  2. 爲什麼它不運行自己重新定義的方法?

回答

2

由於在子類中您沒有定義任何function inherited(),因此必須調用其父方法。正如您引用的評論所說:

...私有方法只對定義它們的類可見,而子類不會看到父級的私有方法。 ...

這就是說,因爲你不必引用孩子的私有方法,任何公開的方法,如:

class child extends base { 
    public function inherited() { 
     $this->overriden(); 
    } 

    // ... 

從我的角度來看,調用$test->inherited()將使用範圍的父類,所以,如果您創建父類的實例並調用$this->inherited()會發生什麼情況。它會輸出基地

試着做我上面說的:在子類中,複製並粘貼父類的繼承方法。它會輸出孩子

我不確定這是否得到很好的解釋,如果是的話,也許它可以幫助你更多地理解,如果不是,有人可以幫助我改善它。

+0

簡單的總結:如果它會輸出'child',那意味着父對'inherited'的實現會調用孩子的'overridden'實現,這顯然違反了「只對定義它們的類可見」規則。 – deceze

+0

是的,如果你想'$ test-> inherited()'輸出'child',你只需要在子類中創建'inherited()'函數。謝謝你的評論@deceze – Condorcho

+0

阿哈,這是關於我如何(也許我並不孤單)理解繼承:事實上作爲一種方法和屬性COPYING。所以我猜想,當子類繼承了'inherited'方法時,它實際上得到了它的一個副本。從這個角度看,孩子調用自己的「繼承」方法,然後調用孩子的「重寫」方法並輸出「孩子」。 好吧,我意識到這不是它的實際工作原理。 :-) –