2012-05-08 58 views
8

如果現在我對ststic有點了解現在我意識到我什麼都不懂。我很困惑,我很難理解,我不能。有人可以解釋這個程序,當使用自我,父母,靜態和如何 我做的所有最小的變化改變結果沒有我無法理解發生了什麼事情。 非常感謝..什麼時候使用self,parent,static和how?

代碼從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(); 
?> 

的出放爲:

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

http://php.net/manual/en/language.oop5.static.php。它說:

將類屬性或方法聲明爲靜態使它們可以訪問而無需實例化該類。

...

由於靜態方法是沒有創建的對象的實例調用,僞變量$ this不可聲明爲static方法內。

調用靜態方法時,因爲不能使用$this,有一個被放置在$this變量沒有實例化的類對象。所以你使用self::

parent::指的是當前類正在擴展的父類。例如,對於C類,父類是B類,對於B類,父類是A類。請參閱http://php.net/manual/en/keyword.parent.php

如果您希望在不實際聲明該類的實例的情況下訪問該函數,則可以使用靜態方法。


在仔細檢查您的問題後,您的鏈接指向延遲靜態綁定。在該頁面的前兩個例子相當清楚地表明瞭static::語法的需要,但澄清您發佈的例子:

看看在A類。foo()方法,它調用static::who()。這意味着方法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和調用自::誰()你會得到三A作爲一個結果。

+0

+1的優點和缺點,用於解釋'static ::'vs'self ::' – webbiedave

+0

感謝您的好解釋 –

相關問題