2011-03-17 29 views
0

檢查下面給出的代碼。我無法理解它是如何調用Class Bar類的testPrivate()方法的。根據我的假設,它應該從Foo類調用方法,即Foo :: testPrivate。php OOP - 與方法可見性有關

Check the demo here

<?php 
    class Bar 
    { 
     public function test() { 
      $this->testPrivate(); 
      $this->testPublic(); 
     } 

     public function testPublic() { 
      echo "Bar::testPublic\n"; 
     } 

     private function testPrivate() { 
      echo "<br>Bar::testPrivate\n"; 
     } 
    } 

    class Foo extends Bar 
    { 
     public function testPublic() { 
      echo "<br>Foo::testPublic\n"; 
     } 

     private function testPrivate() { 
      echo "<br>Foo::testPrivate\n"; 
     } 
    } 

    $myFoo = new foo(); 
    $myFoo->test(); // Bar::testPrivate 
        // Foo::testPublic 
    ?> 

回答

1

如果你想有一個子類,以便能夠在重載父類中定義的方法,該方法已被宣佈爲protected - 而不是private


在這裏,如果你改變你的testPrivate方法定義到:

protected function testPrivate() { 
    echo "<br>Bar::testPrivate\n"; 
} 

和:

protected function testPrivate() { 
    echo "<br>Foo::testPrivate\n"; 
} 

你會得到你所期望的輸出:

Foo::testPrivate 
Foo::testPublic 


欲瞭解更多信息,你應該看看手冊的Visibility部分 - 引用第一個句子:

類成員聲明爲public可以 訪問無處不在。
成員 聲明保護可以訪問 只在類本身和 繼承和父類。
成員聲明爲私有可能 只能由 定義成員的類訪問。

+0

是的..你說得對...但我不清楚這段代碼。 Bar :: test()是公開的。所以它會在Foo類中繼承。所以現在當它從Foo對象被調用時,它應該調用foo類的私有方法,即Foo :: testPrivate。 – 2011-03-17 06:42:30

+0

除了'Bar :: test()'方法在'Foo'類中沒有被重載:它在'Bar'類中,並且,因爲你的'testPrivate'方法是私有的。如果你重載'Foo'類中的'test()'方法,並且'testPrivate'保持私有狀態,那麼將會調用'Foo :: private'。 – 2011-03-17 06:45:08

+0

這就是我的想法。它應該調用Foo :: testPrivate而不是Bar :: testPrivate。但是當我們執行代碼時,它調用Bar :: testPrivate。這是我很混亂。此代碼來自OOP php maual中的visibility - > Method Visibility部分。 – 2011-03-17 06:47:36

1

我想你誤解了該私人方法是什麼。 Foo :: testPrivate()只能從Foo內部調用。您可以通過受保護的方法獲得您描述的行爲。受保護的手段對於課程以及任何擴展它的課程都是可見的。

+0

是......但是Bar :: test()已經全部準備好了,繼承到了Foo。所以它只在Foo邊,可以調用Foo :: testPrivate()...如果我錯了,請糾正我 – 2011-03-17 06:38:43

+0

不,test()仍然屬於Bar。從外部可以將其作爲Foo對象的方法調用,但在其內部仍然是私有的Bar方法。 – 2011-03-17 06:43:31