2013-05-14 84 views
7

我想了解靜態方法,我已經達到了一個令人困惑的地步。如果我創建我的對象的實例(其中類本身不是靜態的),那麼我通常只能訪問公共的,受保護的或內部方法(取決於範圍/封裝)。換句話說,我不能訪問私有方法。爲什麼你不使用靜態方法的所有私人方法?

我讀過,儘管最小的靜態方法比非靜態方法略高效。

因此,當創建一個返回類型爲void的私有方法,並且不包括從本身內部創建對象的引用時,爲什麼您不會將其設置爲靜態?我見過的所有代碼都沒有這樣做,所以我只能假設我錯過了這一點。

+3

出於同樣的原因,爲什麼你不應該使所有的東西都是靜態的,因爲你想從OOP中受益。因此你需要實例。即使私人方法通常與一個實例有關。 – 2013-05-14 13:43:48

回答

29

靜態方法無法訪問類中的非靜態成員數據。

6

靜態方法通常應該是無狀態,因此無法訪問實例狀態。相反,實例方法是有狀態,因此可以讀取和修改實例的狀態。

的無國籍方法的典型例子是:

  • 工廠方法
  • 二元運算
  • ...

當然,靜態方法並不總是無國籍不過,有靜態有形方法的樣本。有一個類然後單狀態:

  • 辛格爾頓
  • 實例池
  • ...

這些實現需要稍微小心,雖然,因爲類的狀態也由進程內的所有線程共享。

0

您在代碼中看到的大多數方法都會以某種方式使用不是靜態的類變量/屬性。這些不能從靜態上下文訪問。這意味着在一個靜態方法中,您只能訪問此類的靜態成員,而不能訪問特定於對象的靜態成員。

1

我讀過,雖然最小的靜態方法比非靜態方法略高效。

這並非無條件地成立:只有方法可以是static,但不會因爲省略而產生static會更有效。否則,您需要手動傳遞對象的引用,以提升遊戲場。而且,CLR的優化程度非常高,以至於難以衡量差異。

要回答你的問題,如果方法不通過屬性或變量訪問實例狀態,沒有理由使方法爲非靜態方法。但是,爲了便於閱讀,訪問每個實例狀態的所有方法都應該是非靜態的,因爲通過靜態方式和手動傳遞實例沒有性能。

爲了說明這一點,你應該這樣做

private void AddCount(int number) { 
    current += number; 
} 

,而不是這樣的:

// Do not do this! 
private static void AddCount(MyClass obj, int number) { 
    obj.current += value; 
} 
1

您不能訪問非靜態成員在類,如果你做到這一點。您可以將任何實例變量作爲參數傳遞給私有靜態函數,但特別是當函數與大量實例數據交互時,這會導致一些非常臃腫且難以閱讀的代碼。如果您使用的是類的實例成員,並且不是沒有類的實例即可完成的操作,則不應將其設置爲靜態。

作爲基本的一般規則,除非對類的所有實例都至關重要,否則我不會將變量或函數設爲靜態。當然也有例外,但是如果你只是簡單地使所有的私有方法都是靜態的,那麼你很可能會對付OOP範例。

0

兩個原因浮現在腦海中:

  1. 你不能訪問你的類的其他非靜態成員(如上所述)
  2. 你不能在子類中重寫靜態方法

IMO,靜方法應該更多地作爲例外。如果您希望在具有依賴注入容器的應用程序中「輕鬆訪問」某個功能,則最好使用單例bean並注入它,因爲如果需要,您仍然可以輕鬆切換實現。

對於靜態方法 - 擴展方法,.NET有一個特定的用例。所以如果你希望你的功能作爲擴展方法提供,你必須使用靜態。

相關問題