2013-03-29 60 views
4

我有一個只有靜態方法擴展類的子類。我想讓這個子類成爲單例而不是靜態的,因爲原始開發者確實想要一個單例,但是使用了靜態(顯而易見,因爲靜態類中的每個方法都調用Init()函數(基本上是構造函數))。非靜態調用靜態方法

大部分父方法不需要在孩子被覆蓋,但我想,以避免寫這樣的方法:

public function Load($id) 
{ 
    return parent::Load($id); 
} 

的時候我寧願不要覆蓋方法,只是使用:

$child->Load($id); 

是否可以非靜態地調用靜態方法?是否有可能使用實例對象來擴展靜態對象?我知道我可以嘗試它,它可能會工作(PHP是非常寬容的),但我不知道是否有什麼我應該關心的。

+0

爲什麼不只是使用普通的舊PHP對象?沒有所有的靜態和單例廢話你可能[不需要]頭痛(http://stackoverflow.com/questions/4595964/who-needs-singletons/4596323#4596323)。另外,是可測試的。畢竟,它被稱爲面向對象*而不是面向類。 – Gordon

+0

Singleton是一種設計模式。它使用一個「普通的舊」php對象,它只是意味着它有一個私有的構造函數和一個靜態的GetInstance方法。它確保只存在一個對象的實例,但由於它有一個構造函數,所以不必在每個方法中初始化變量。 – Mike

+0

我知道單身是什麼:)我所說的是:你不需要它。請參閱我的初始評論中的鏈接。你正在用靜力學和單身生活讓你的生活變得悲慘。 – Gordon

回答

9
  • 你能繼承靜態方法嗎?

  • 你能重寫靜態方法?

是的,但只是作爲PHP 5.3的做他們的工作,你所期望的:(即self結合實際的類,而不是它的定義類)http://www.php.net/manual/en/language.oop5.static.php

  • 是否可以非靜態地調用靜態方法?

是的,但會丟失$this。你還沒有得到警告,但也沒有理由認爲它是錯誤的。

+0

所以你推薦使用第一種方法,我覆蓋並調用父級靜態? – Mike

+1

如果您使用PHP5.3或更高版本,是的。此外,它覆蓋*不覆蓋。 – Halcyon

+11

你不會得到任何警告。只有在您靜態調用非靜態方法時,纔會出現警告。 –

7

兩部分答案。

首先,關於題目問題:非靜態地調用一個靜態方法是很好的; @ SamDark的評論是正確的。它不會產生警告,也不會導致任何小貓被謀殺。試試看:

<?php 

class test { 
    public static function staticwarnings(){ 
     echo "YOU ARE (statically) WARNED!\n"; 
    } 
} 

error_reporting(E_ALL); 

$test = new test(); 
echo "\n\ncalling static non-statically\n"; 
$test->staticwarnings(); 

如果你有一個實例參考,$this,在靜態方法,那麼你會得到一個致命的錯誤。但不管你怎麼稱呼它都是如此。

再次,沒有警告,也沒有任何小貓死亡。答案


第二部分:

呼叫從一個壓倒一切的子類的重載父功能需要一種叫做"scope resolution"。 OP在他們的方法中做的是不調用靜態方法。 (或者至少,它不一定是;我們看不到父實現)。關鍵是,使用父關鍵字不是一個靜態調用。如果在擴展類中使用::運算符,則顯式父類名稱上的使用也不是靜態調用。

爲什麼該文檔鏈接如此奇怪地命名?這實際上是希伯來語。如果您遇到過與之相關的錯誤,您可能會觀察到令人愉快的解析器錯誤代碼T_PAAMAYIM_NEKUDOTAYIM