2012-10-09 36 views
4

我從php手冊中的示例中感到困惑。這是關於可見性。這裏是例子。php手動可見性示例困惑

class Bar { 
    public function test() { 
     $this->testPrivate(); 
     $this->testPublic(); 
    } 
    public function testPublic() { 
     echo "Bar::testPublic\n"; 
    } 
    private function testPrivate() { 
     echo "Bar::testPrivate\n"; 
    } 
} 
class Foo extends Bar { 
    public function testPublic() { 
     echo "Foo::testPublic\n"; 
    } 
    private function testPrivate() { 
     echo "Foo::testPrivate\n"; 
    } 
} 
$myFoo = new foo(); 
$myFoo->test(); 
?> 

http://www.php.net/manual/en/language.oop5.visibility.php

這個例子輸出

Bar::testPrivate 
Foo::testPublic 

請你能解釋一下這是如何發生的呢?

爲什麼兩個testPublic()都不叫?

我在Bar類構造中放了一個var_dump($this)。它打印object(Foo)[1]。我知道的事情是私人物業可以被稱爲同一類。

那麼如何調用「Bar::testPrivate」?

回答

4

那麼如何調用「Bar :: testPrivate」?

當你調用$myFoo->test(),它運行在Bar上下文中的代碼,因爲Foo類沒有覆蓋它。

裏面Bar::test(),當$this->testPrivate()被調用,解釋將着眼於Foo第一但該方法是私有的(和派生類的私有方法不能從Bar調用),如此這般一個級別,直到它可以找到一種合適的方法;在這種情況下,這將是Bar::testPrivate()

相反,當$this->testPublic()被調用時,解釋器立即在Foo中找到合適的方法並運行它。

編輯

爲什麼都testPublic()不叫?

當你運行$this->testPublic()時,只有一個方法被調用,這是最遠的一個方法(根據到基類的距離)。

如果Foo::testPublic()還需要執行父級的實現,則應該在該方法內寫入parent::testPublic()

+3

+1爲什麼不能'test()'(它是Bar的'test()')調用'Foo'的'testPrivate()'?因爲它是私密的,你不想讓父母撫摸他們孩子的私生子,你呢? – NullUserException

+0

@NullUserException這是一個很好的觀點哈哈! –

+0

關於'testPublic()'的混淆的一部分,我想,PHP是替代重寫而不是重寫的優化。這意味着PHP不會在孩子中調用父母的方法,除非你明確地要求它這樣做(例如:'parent :: testPublic();')。 – NullUserException

1

Private並不意味着你不能稱之爲它。這意味着您只能從當前類別中調用它。 Public表示您可以撥打任何類別

要調用Bar::testPrivate,試試這個:

$Bar->testPublic(); 

parent::testPublic(); 

,但你不能說$Bar->testPrivate()因爲該方法是private

+0

這不回答這個問題。 – NullUserException

+0

對不起,誤解了這個問題。固定。 –

2

您的功能在於Bar類,您正在使用指針調用成員函數。

嘗試將函數test()改爲Foo類,看看會發生什麼。輸出應爲:

Foo::testPrivate 
Foo::testPublic 

在你的例子中,Bar的私有函數被調用,因爲它只適用於那個類。 Foo類沒有test函數,因此Bar類的測試函數無權調用它們。

然後,類Foo的公用函數被調用,而不是Bar的由於函數重載。

這兩個類都有該名稱的函數,所以子類的函數具有重要性。

+1

我從你的答案中瞭解了重載的東西。多謝,夥計.. – Namal

1

你叫

$myFoo->test(); 

見功能test

public function test() { 
    $this->testPrivate(); 
    $this->testPublic(); 
} 

當這個被稱爲上Bar類(包括繼承的類)的實例,它調用testPrivatetestPublic

這些方法在類別Foo中被覆蓋,這意味着使用Foo的方法。您可以隨時調用基類的方法:

// in Foo 
public function testPublic() { 
    parent::testPublic(); 
    echo "Foo::testPublic\n"; 
}  

Bar::testPrivate叫,因爲它是private,而不是由Foo::testPrivate覆蓋。

查看更多herehere

0

Foo類擴展了Bar類。然後調用函數測試,這是在Bar中定義的。在這個函數中有兩個調用。一個向公衆開放,一個向酒吧的私人功能。

1

我猜用戶'歐米茄在2093點ES'(http://www.php.net/manual/en/language.oop5.visibility.php#109324)的評論是描述相同的事情。有人說:「在父類中定義的方法不能訪問從它們繼承的類中定義的私有方法,但它們可以訪問受保護的方法。」

Bar::test()方法你的情況$this目的是Foo類型(您的var_dump證明)的。由於Foo::testPrivate()方法是私有方法,因此無法從父類Bar訪問,並且唯一可以訪問的方法仍爲Bar::testPrivate()(嘗試評論定義,並且會出現致命錯誤)。這就是爲什麼第一個輸出是Bar::testPrivate。因爲$thisFoo類型和方法被定義爲公共。

簡而言之,私有方法只能從定義它們的類中訪問。他們既不能從孩子也不能從父母班級進入。

爲了使該方法可以從子類或父類訪問,使其受到保護。例如,如果您在兩個課程中都使testPrivate()方法受到保護,則它將打印Foo::testPrivate Foo::testPublic