何時用靜態方法,何時用例項方法
例項方法,當你給乙個類寫乙個方法,如果該方法需要訪問某個例項的成員變數時,那麼就將該方法定義成例項方法。一類的例項通常有一些成員變數,其中含有該例項的狀態資訊。而該方法需要改變這些狀態。那麼該方法需要宣告成例項方法。
靜態方法正好相反,它不需要訪問某個例項的成員變數,它不需要去改變某個例項的狀態。我們把該方法定義成靜態方法。
第一種方式, 宣告例項,呼叫例項方法
當乙個類有多個例項,例如學生這個類,例項可以有學生甲,學生乙,學生丙,等等,我們就用第一種方式。在多執行緒的情況下,只要每個執行緒都建立自己的例項,那麼第一種方法通常是執行緒安全的。
第二種方式,通過乙個靜態的例項,去呼叫例項方法
這種情況比較特殊,通常是整個程式裡該類唯一的乙個例項,我們通過呼叫該例項的例項方法來改變該例項的某些狀態。這乙個例項在多執行緒的情況下,通常是執行緒不安全的。除非我們給這個例項加鎖。防止其他執行緒訪問該例項。
第三種方式,直接呼叫靜態方法
這種情況下靜態方法不需要去改變某個例項的狀態。只要得到少量的引數就可完成既定事情。比如判斷乙個檔案是否存在,只要給個檔案路徑和檔名,就能知道該檔案是否存在。
c#中的方法有兩種:例項方法,靜態方法。方法一般都是指標引用。使用了static修飾符的方法為靜態方法,反之則是例項方法。靜態方法是全域性的,例項方法是區域性的。二者的記憶體分配機制不同,靜態方法是在程式啟動時載入為程式集分配記憶體時就以經分配記憶體,而例項方法是在程式執行的時候載入到記憶體,靜態方法和靜態變數的宣告週期和程式集是一樣的
靜態方法效率上要比例項化高,靜態方法的缺點是不自動進行銷毀,而例項化的則可以做銷毀。靜態方法和靜態變數建立後始終使用同一塊記憶體,而使用例項的方式會建立多個記憶體。
靜態方法是一種特殊的成員方法,它不屬於類的某乙個具體的例項,而是屬於類本身,所以在外部呼叫靜態方法時,可以使用"類名.方法名"的方式,也可以使用"物件名.方法名"的方式。而例項方法只有後面這種方式。也就是說,呼叫靜態方法可以無需建立物件。
靜態方法只能訪問靜態成員,例項方法可以訪問靜態和例項成員。之所以不允許靜態方法訪問例項成員變數,是因為static方法是類中的乙個成員方法是屬於整個類,例項成員變數是屬於某個物件的,而靜態方法在執行時,並不一定存在物件。同樣,因為例項方法可以訪問例項成員變數,如果允許靜態方法呼叫例項方法,將間接地允許它使用例項成員變數,所以它也不能呼叫例項方法。static內部只能出現static變數和其他static方法,而且static方法中不能使用this關鍵字,因為它是屬於整個類的。main()方法是乙個典型的靜態方法,它同樣遵循一般靜態方法的規則,所以它可以由系統在建立物件之前就呼叫。
那麼在程式中什麼地方可以利用靜態欄位和靜態構造方法:通常適用於於一些不會經常變化而又頻繁使用的資料,比如連線字串,配置資訊等,當滿足上面所 說的兩點時,進行一次讀取,以後就可以方便的使用了,同時也節約了託管資源,因為對於靜態成員,乙個靜態欄位只標識乙個儲存位置。對乙個類無論建立了多少 個例項,它的靜態字段永遠都只有乙個副本(副本我理解為只有一塊記憶體靜態成員存在於記憶體,非靜態成員需要例項化才會分配記憶體)。 公用的處理函式,使用靜態方法應該沒有問題..牽涉到資料共享,靜態變數的函式要多考慮...靜態變數要小心使用..靜態方法 原理就是共享**段 共享**段不會產生任何問題 因為**段都是給cpu作為"讀取"用的,除非你進行惡意"修改"執行時的**段 所以靜態方法是可以放心使用的靜態變數 原理就是共享資料段 同上 只要沒有進行"寫入"操作就不會產生問題 但是資料通常都是用於讀和寫 所以靜態變數要注意使用
靜態方法和例項方法常見誤區
1、大家都以為「 靜態方法常駐記憶體,例項方法不是,所以靜態方法效率高但佔記憶體。」
事實上,他們都是一樣的,在載入時機和占用記憶體上,靜態方法和例項方法是一樣的,在型別第一次被使用時載入。呼叫的速度基本上沒有差別。
2、大家都以為「 靜態方法在堆上分配記憶體,例項方法在堆疊上」
事實上所有的方法都不可能在堆或者堆疊上分配記憶體,方法作為**是被載入到特殊的**記憶體區域,這個記憶體區域是不可寫的。
方法佔不占用更多記憶體,和它是不是static沒什麼關係。
因為欄位是用來儲存每個例項物件的資訊的,所以欄位會占有記憶體,並且因為每個例項物件的狀態都不一致(至少不能認為它們是一致的),所以每個例項物件的所以欄位都會在記憶體中有一分拷貝,也因為這樣你才能用它們來區分你現在操作的是哪個物件。
但方法不一樣,不論有多少個例項物件,它的方法的**都是一樣的,所以只要有乙份**就夠了。因此無論是static還是non-static的方法,都只存在乙份**,也就是只占用乙份記憶體空間。
同樣的**,為什麼執行起來表現卻不一樣?這就依賴於方法所用的資料了。主要有兩種資料**,一種就是通過方法的引數傳進來,另一種就是使用class的成員變數的值……
3、大家都以為「例項方法需要先建立例項才可以呼叫,比較麻煩,靜態方法不用,比較簡單」
事實上如果乙個方法與他所在類的例項物件無關,那麼它就應該是靜態的,而不應該把它寫成例項方法。所以所有的例項方法都與例項有關,既然與例項有關,那麼建立例項就是必然的步驟,沒有麻煩簡單一說。
當然你完全可以把所有的例項方法都寫成靜態的,將例項作為引數傳入即可,一般情況下可能不會出什麼問題。
從物件導向的角度上來說,在抉擇使用例項化方法或靜態方法時,應該根據是否該方法和例項化物件具有邏輯上的相關性,如果是就應該使用例項化物件 反之使用靜態方法。這只是從物件導向角度上來說的。
如果從執行緒安全、效能、相容性上來看 也是選用例項化方法為宜。
靜態方法和例項方法
靜態方法 靜態方法是不屬於特定物件的方法,靜態方法可以訪問靜態成員變數,靜態方法不可以直接訪問例項變數,可以在例項函式呼叫的情況下,例項變數做為引數傳給靜態方法。靜態方法也不能直接呼叫例項方法,可以間接呼叫,首先要建立乙個類的例項,然後通過這一特定物件來呼叫靜態方法。例項方法 乙個例項方法的執行與特...
06 靜態方法和例項方法
doctype html en utf 8 jquery的靜態方法和例項方法 title script 1 定義乙個類 function aclass 2 給這個類新增乙個例項方法 直接新增給類的就是靜態方法 aclass.staticmethod function 靜態方法通過類名呼叫 aclas...
js 靜態方法和例項方法
function f function.prototype.b function var f new f typeof f object typeof f function f.af.b function c 靜態方法 function test test.to function res test....