2012-02-09 83 views
15

爲什麼在PHP中可以通過某個類的實例訪問靜態方法,但不僅僅是通過類型名稱?PHP中的靜態方法

更新:我是.net開發人員,但我也與PHP開發人員一起工作。最近我發現了這個關於從實例中調用的靜態方法的時刻,並且無法理解爲什麼它可能是有用的。

實施例:

class Foo 
{ 
    public static Bar() 
    { 
    } 
} 

我們可以接受這樣的方法:

var $foo = new Foo(); 
$foo.Bar(); // ?????? 
+4

靜態方法和屬性是有點棘手,在第一。所有你需要記住的是,一個靜態方法或屬性是可以在沒有實例化對象的情況下使用的。 – EGHDK 2012-02-09 07:12:39

+0

你能澄清一下你的代碼片斷是什麼意思嗎?你的問題有些含糊。 – deceze 2012-02-09 07:28:12

+0

這不是PHP特有的。在Python中,您還可以訪問實例中使用'@ staticmethod'裝飾器修飾的方法,唯一的區別是靜態方法不會接收調用它們的上下文(對象)。 – Tadeck 2012-02-09 07:44:59

回答

24

在PHP

類是使用例如新的關鍵字實例化;

$MyClass = new MyClass();

並且可以通過使用任一範圍解析操作者或對象引用操作者訪問的靜態方法或屬性。例如如果類MyClass包含靜態方法Foo()那麼您可以通過任何方式訪問它。

$MyClass->Foo(); Or MyClass::Foo()

唯一規則是靜態方法或屬性不對象上下文。例如,您不能在靜態方法中使用$this

+1

儘管使用實例,它也可以工作:'$ class-> staticMethod()' – dmitry 2012-02-09 07:25:57

+5

@Ibrahim - 實際上,這是不正確的。您可以從類的實例或類本身訪問靜態方法和非靜態方法。只有當你調用靜態引用'$ this'的方法時,纔會出現錯誤。 – 2012-02-09 07:29:08

+1

@ confused-demon從來不知道PHP允許這個,謝謝:) – 2012-02-09 07:30:53

3

爲什麼在PHP中可以通過某個類的實例訪問靜態方法,但不僅僅是通過類型名稱?

與您可能習慣的.NET不同,PHP具有動態類型。試想一下:

class Foo 
{ 
    static public function staticMethod() { } 
} 

class Bar 
{ 
    static public function staticMethod() { } 
} 

function doSomething($obj) 
{ 
    // What type is $obj? We don't care. 
    $obj->staticMethod(); 
} 

doSomething(new Foo()); 
doSomething(new Bar()); 

因此,通過允許訪問通過對象實例的靜態方法,可以更方便地調用在不同類型的同名靜態函數。

現在我不知道是否有一個很好的理由,通過->訪問靜態方法是允許的。 PHP(5.3?)也支持:

$obj::staticMethod(); 

這或許不那麼令人困惑。當使用::時,它必須是一個靜態函數來避免警告(不像->,它允許)。

+0

在你的例子中,應該使用帶接口的非靜態方法,因爲這樣使用靜態方法有點混亂不是嗎? – donRumatta 2012-02-09 10:21:14

+0

@donRumatta,我不會聲稱以上是好的代碼。但由於PHP的動態特性,接口並不是絕對必要的,許多人在沒有它們的情況下編碼。請注意,PHP並不總是有很好的OOP支持,所以對「爲什麼」的一些答案只是「過去版本的糟糕的設計決策」。 – Matthew 2012-02-09 16:26:37

11
Class Do { 
    static public function test() { 
     return 0; 
    } 
} 

使用這樣的:

echo Do::test();