2012-04-08 9 views
4

私はLSB機能についてphpマニュアルを読んでいますが、静的コンテキストではどのように動作するのか理解していますが、非静的コンテキストではあまり理解できません。マニュアルの例はこれです:PHPで遅い静的バインド

<?php 
class A { 
    private function foo() { 
     echo "success!\n"; 
    } 
    public function test() { 
     $this->foo(); 
     static::foo(); 
    } 
} 

class B extends A { 
    /* foo() will be copied to B, hence its scope will still be A and 
    * the call be successful */ 
} 

class C extends A { 
    private function foo() { 
     /* original method is replaced; the scope of the new one is C */ 
    } 
} 

$b = new B(); 
$b->test(); 
$c = new C(); 
$c->test(); //fails 
?> 

出力はこれです:

success! 
success! 
success! 


Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9 

私はAでプライベートメソッドがBに継承することができる方法、クラスBのために理解していませんか?誰でもここで起こっていることを通して私を歩くことができますか?どうもありがとう!

+2

一般的な注意点:静的でないプロパティやメソッドを呼び出すには、 '::'を使わないでください。 – mc10

+0

@ mc10 - 'static ::'はPHP 5.3で[late static binding](http://php.net/manual/en/language.oop5.late-static-bindings.php)を呼び出す方法です。しかし、私は静的メンバーのためにそれを予約する必要があることに同意します。 –

答えて

3

レイトスタティックバインディングを使用すると、コールで選択されたメソッドだけが変更されます。メソッドが選択されると、それが呼び出されるかどうかを判断するための可視性ルールが適用されます。

Bの場合、A::testは、A::fooを見つけて呼び出します。 Bのコメントが正しくない - fooBにコピーされません。プライベートなので、A::testのようなAの他のメソッドからのみ呼び出すことができます。遅延静的バインディングメカニズムは新しいプライベートメソッドC::fooを見つけたが、Aの方法は、それへのアクセスを持っていないので、

Cは失敗します。

混乱を避けるため、静的フィールドとメソッドにlate static bindingを予約することをお勧めします。

+0

ありがとうございます。しかし、なぜ私はそれが私的であるので、foo()がBによって継承されるのか分からない。 $ b-> test()が実行されたとき、ここで$ bは実際にクラスAのオブジェクトとして扱われるのでしょうか? – Michael

+3

@Michael - 技術的に 'A :: foo'はプライベートなので継承されません。重要なのは、 'A'のメソッドだけが呼び出すことができるということです。 –

+0

まさに、そのような親から子のプライベートメソッドを呼び出すことはできません。 – BenOfTheNorth

関連する問題