2012-05-08 11 views
8

今のところ私は少し愚かなことを理解していましたが、今は何も理解していないことが分かります。私はとても混乱しており、私は理解するのに苦労し、私はできません。誰かがこのプログラムを自己、親、静的、そしてどのように使うのかを説明することができます 私が行う最小限の変更は、それがなくても結果を変えます。何が起こっているのか理解できません。 おかげhttp://docs.php.net/language.oop5.late-static-bindings自己、親、静的およびどのように使用する場合は?

<?php 
class A { 
    public static function foo() { 
     static::who(); 
    } 

    public static function who() { 
     echo __CLASS__."\n"; 
    } 
} 

class B extends A { 
    public static function test() { 
     A::foo(); 
     parent::foo(); 
     self::foo(); 
    } 

    public static function who() { 
     echo __CLASS__."\n"; 
    } 
} 
class C extends B { 
    public static function who() { 
     echo __CLASS__."\n"; 
    } 
} 

C::test(); 
?> 

からたくさん..

コードアウトプットは以下のとおりです。http://php.net/manual/en/language.oop5.static.php

A 
C 
C 

答えて

17

Late Static Bindingという概念を理解する必要があります。具体的には、の識別子がコード/データにバインドされている場合はとなります。早期にバインドするようにPHPに指示することができます(self::)またはそれ以降(static::)。

スリミング我々が得る二つのクラスにまで例:

class A { 
    public static function foo() { 
     self::who(); // PHP binds this to A::who() right away 
     static::who(); // PHP waits to resolve this (hence, late)! 
    } 

    public static function who() { 
     echo __CLASS__."\n"; 
    } 
} 

class B extends A { 
    public static function test() { 
     self::foo(); 
    } 

    public static function who() { 
     echo __CLASS__."\n"; 
    } 
} 

B::test(); 
+0

ありがとうございました –

+1

奇妙な!私は後者のバージョンがデフォルトであると思っていたでしょう。つまり、なぜ私の子クラスはメソッドを定義して、親バージョンをデフォルトで呼び出すのでしょうか?しかし、私は期待していたようなPHP標準が何であったかは思い出せません。 – jsh

+1

誰かがもっと説明できますか?両方の長所と短所を説明してください。 – Rafael

6

ルック。それは言う:

クラスプロパティまたはメソッドを静的として宣言すると、クラスのインスタンス化を必要とせずにアクセス可能になります。

...

静的メソッドは、作成されたオブジェクトのインスタンスなしで呼び出し可能なので、疑似変数$これはstaticとして宣言されたメソッド内部では使用できません。

静的メソッドを呼び出すときに、$this変数に配置すべきインスタンス化クラスオブジェクトが存在しないので、あなたは$thisを使用することはできません。したがって、self::を使用します。

parent::は、現在のクラスが拡張している親クラスを参照しています。例えば、クラスCの場合、親クラスはクラスBであり、クラスBの場合、親クラスはクラスAです。http://php.net/manual/en/keyword.parent.phpを参照してください。

実際にそのクラスのインスタンスを宣言せずに関数にアクセスできるようにするには、静的メソッドを使用します。


あなたの質問を詳しく調べると、リンクはLate Static Bindingsを指しています。そのページの最初の2つの例では、かなり明確にstatic::構文の必要性を示しますが、あなたが投稿たとえば明確にする:

はそれがstatic::who()を呼び出すクラスA内foo()方法を見てみましょう。つまり、メソッドwho()は、関数が定義されているクラスのスコープではなく、関数を呼び出したクラスのスコープで呼び出されます。したがって、C::foo()に電話する場合は、Cをエコーし​​ます。

代わりにself::who()を呼び出すと、A::who()が呼び出されます。クラスAの中でself::はA.を指しているので

うまくいけば助けてください。

+1

この回答は、 'static ::'と 'self ::'が使用されているときに呼び出される関数には触れません。これは実際にはサンプルコードの最も重要な側面です。 – webbiedave

+0

@webbiedave:良い点、改訂された答え。 – Travesty3

+0

+1私はあなたの編集を見る前に、この点についても回答を掲載しました。 – webbiedave

5

答えの鍵は静的です::()、静的な覚えは::あなたが(実際のクラスでメソッドを呼び出すこと私たちの場合 - C)。

ので、C ::テスト()の実行を次のように

A::foo(); -> calls to A::foo() therefor echo A 
parent::foo(); -> calls to C parent (which is B), B::foo() inherits A::foo() which calls to static::who(), but our actual class is C, therefor echo C 
self::foo(); -> again calls to foo() which calls to static::who() with our actual class C 

かの代わりの静的::者()fooが呼んでいた自己::()を使用すると、結果として3 Aを取得する必要があります。

+0

+1 'static ::' vs 'self ::'を説明するために – webbiedave

+0

ありがとうよい説明 –

関連する問題