2008-10-14 71 views
12

所以我明白什麼是靜態方法或字段,我只是想知道什麼時候使用它們。也就是說,在編寫代碼時,什麼設計適合使用靜態方法和字段。什麼時候應該寫靜態方法?

一個常見的模式是使用靜態方法作爲靜態工廠,但這可以通過重載構造函數來輕鬆完成。正確?例如:

var bmp = System.Drawing.Bitmap.LoadFromFile("Image01.jpg"); 

至於靜態字段,創建singelton對象最好用嗎?

回答

15

它提供了一個更好的想法,當你使用靜態工廠時 - 它也讓你有不同的工廠採用相同的參數類型,但有不同的含義。例如,想象一下,如果Bitmap具有LoadFromResource(字符串) - 將不可能有兩個都帶有字符串的構造函數。

編輯:從stevemegson在評論

一個靜態工廠也可以返回空值,並且可以更容易地返回一個實例,它從緩存中得到。我的很多類都有一個靜態的FromId(int)來從主鍵獲取一個實例,如果有的話就返回一個現有的緩存實例。

+0

靜態工廠也可以返回null,並且可以更容易地返回它從緩存中獲取的實例。我的很多類都有一個靜態的FromId(int)來從主鍵獲取一個實例,如果有的話就返回一個現有的緩存實例。 – stevemegson 2008-10-14 22:02:24

21

靜態方法通常適用於不需要類實例中的任何數據(來自this)的操作,並且可以僅使用它們的參數執行其預期目的。
一個簡單的例子是計算兩點之間的距離並且不需要實例的方法Point::distance(Point a, Point b);

靜態字段對常量沒有用處,常用類型的所有實例都使用這些常量。

+0

所以我們只有在想訪問'this'類的數據成員時才應該創建非靜態方法? – JerryGoyal 2016-10-18 07:44:53

7

只要你有獨立於實例狀態的函數,就可以使用靜態方法。不依賴於任何實例字段。

方法依賴的非本地狀態越少,它就越容易理解,所以static對讀者來說是一個有用的信號。

+0

如果我正確理解這一點,你可以說_alawys_使用靜態方法。但是這並不正確。 .NET Base Class Libraries中有很多情況,其中方法可能是靜態的,但不是。 – 2008-10-14 20:07:43

6

我通過記住實例方法在單個對象上工作或在靜態方法爲類執行某些操作時保持清楚。

在LoadFromFile()的情況下,您需要一個靜態方法,因爲如果加載失敗,則需要空引用 - 實例尚不存在。如果您將它作爲構造函數實現,則必須在失敗時拋出Exception。

statics的其他好處:比較(obj a,obj b),數據對象的刪除(obj a)(對象無法自行刪除,因爲它的引用仍在),或者靜態類的過程代碼誠實地不能在一個對象中建模。

0

當類的客戶端沒有要使用的類的實例時,您可以使用靜態方法。例如,Singleton設計模式用於確保系統中只存在一個類的實例。它要求Singleton的構造函數是私有的,這樣客戶端才能創建實例。

所以,如果你不能創建一個實例,你如何訪問類的實例方法?通過調用返回該類的Singleton實例的靜態方法。

這當然只是一種情況,但還有很多其他情況。

0

這裏是您可能希望使用靜態方法的一些例子:

1)當該功能不使用任何成員變量。你不必在這裏使用靜態方法,但如果你這樣做通常會有幫助。

2)使用工廠方法創建對象時。如果您不知道要提前創建的類型,那麼它們特別有用:例如

class AbstractClass { 
    static createObject(int i) { 
     if (i==1) { 
      return new ConcreteClass1(); 
     } else if (i==2) { 
      return new ConcreteClass2(); 
     } 
    } 
} 

3)當您正在控制或追蹤該類的實例化數量時。 Singleton是這方面最常用的例子。

4)聲明常量時。 5)對類的多個對象進行操作,例如排序或比較操作,並且不與任何特定實例綁定。

6)在對象的第一個實例化之前必須完成特殊處理。

0

只要有一個函數不依賴於該類的特定對象,就應該使用靜態方法。

添加static關鍵字沒有任何壞處:它不會破壞引用它的任何代碼。因此,例如,下面的代碼是有效的,你是否擁有「靜態」的關鍵字:

class Foo 
{ 
    public Foo(){} 
    public static void bar(){} // valid with or without 'static' 
    public void nonStatic(){ bar(); } 
} 

... 
Foo a = new Foo(); 
a.bar(); 

所以,你應該加上「靜」,以任何方法就可以了。

相關問題