靜態方法和實例化方法的區別

這是一個常常被時時提出來的問題,不少時候咱們覺得理解了、懂了,但深究一下,咱們卻發現並不懂。
方法是咱們天天都在寫得,不少程序員大多都使用實例化方法,而不多使用靜態方法,問緣由也說不出來因此然,或者簡單的回答二者定義的區別,靜態方法不須要new就可使用 實例化方法須要new了之後纔可使用。。。。咱們真的理解了嗎?
從實際項目開發提及,這裏有開發項目的三種方式:
開發項目中把BLL和DAL分開,在BLL調用DAL的代碼。
1、在DAL中使用靜態方法,不建立實例直接調用(大概有不少人都使用這種方式開發 )
class DAL
{
public static string GetUserName(...);
}
在BLL中調用:
DAL.GetUserName();
2、在DAL中使用實例方法,採用靜態成員模式(或Singleton)經過實例來調用:
class DAL
{
public static readonly DAL dal = new DAL();
public string GetUserName(...);
}
在BLL中調用:
DAL.dal.GetUserName();
3、在DAL中使用實例方法,每次調用以前先建立DAL對象的實例:
class DAL
{
public string GetUserName(...);
}
在BLL中調用:
DAL dal = new DAL();
dal.GetUserName();
---------------------------------------------------------------
開發方式一:我覺得在一些狀況下(好比 調用多個數據庫、GetUserName(...)內部處理操做部分)會出現線程安全的嫌疑。這種開發方式不用New出對象,因此很廣泛。
開發方式二:應該可能是應用在cs模式下,DAL在整個項目只會有一個對象存在,若是出如今B/S 我想不能兼容多種問題狀況。並且也有線程安全的問題。
開發方式三:應該是廣泛使用的,可以兼容各類問題,也不會有線程不安全的嫌疑出現。
特別說明一下:在MS的pet3.0之前的版本 都採用了方式二,而到pet3.0和之後的版本 都採用了方式三,並且特別在開發說明文檔中明確的解釋了一下。我想應該是從兼容性上考慮的,從性能上方式二並不比方式三真正的高多少。
-------------------------------------------------------------------------
我特地以「你怎麼理解並使用靜態方法和實例化方法的?」這樣的問題詢問了多位程序員,他們開發的語言也不盡相同(c 、c++、java、c#)
如下是他們的回答:
海龍說:
公用的方法,並且是一些零散的 通常用靜態方法
張偉說:
幾乎沒有區別,若是不須要實例化,就用靜態方法;若是爲了穩妥,就用實例方法,這樣纔可調用其餘實例方法和變量 。
蕭遠山說:
靜態方法比較少用,由於他在一啓動就實例化了,比較佔資源,固然,,配合單例模式仍是比較好用的
比較多的用在數據鏈接上,我避免使用的原則就是減小資源消耗。
張新波說:
靜態方法意味着我在調用前不須要進行對其所屬的類進行new操做,我主要會在工具類裏面用到靜態方法。

向詳說:
靜態就是類的,實例就是對象的。
靜態方法和實例方法的區別之處還有一個地方:靜態方法不須要依賴類當中的屬性,能在這個方法中封閉的完成一個功能。實例方法更多的會使用到類當中的屬性。
winson_張林說:
最大的區別在於內存。
靜態方法在程序開始時生成內存,實例方法在程序運行中生成內存,
因此靜態方法能夠直接調用,實例方法要先成生實例,經過實例調用方法,靜態速度很快,可是多了會佔內存。
任何語言都是對內存和磁盤的操做,至因而否面向對象,只是軟件層的問題,底層都是同樣的,只是實現方法不一樣。
靜態內存是連續的,由於是在程序開始時就生成了,而實例申請的是離散的空間,因此固然沒有靜態方法快,
並且靜態內存是有限制的,太多了程序會啓動不了。
showlover說:
靜態方法與實例方法各有本身的用處...
是定義成靜態方法,仍是定義成實例方法,還要看具體狀況,好比方法自己與類型沒有太大的關係,能夠定義成靜態方法..
用實例方法,固然須要你先建立實例,才能調用實例方法,而靜態方法則不須要..
從性能上說,靜態方法效率要稍微高一些,可是它會常駐內存...
一些狀況下使用靜態方法是有好處的,由於對於靜態方法不管你有多少個實例,
內存中要維護的一份拷貝。同時,某些方法,確實使用靜態是比較恰當的..
Q.yuhen說:
這個問題牽扯到的東西比較多,諸如設計模式等等。簡單點說,靜態方法用來執行無狀態的一個完整操做,實例方法則相反,它一般是一個完整邏輯的一部分,而且須要維護必定的狀態值。
若是用內存和效率來區分使用Static Method、Instance Method 就回到過去結構化編程了。使用那種方法的根本出發點仍是圍繞面向對象來進行的。
 
陳亮說:
靜態方法和全局函數差很少的,實例方法是一個類裏面的方法。
 
總結:你們對這個問題都有一個共識:那就是實例化方法更多被使用和穩妥,靜態方法少使用。
有時候咱們對靜態方法和實例化方法會有一些誤解。
一、你們都覺得「 靜態方法常駐內存,實例方法不是,因此靜態方法效率高但佔內存。
事實上,他們都是同樣的,在加載時機和佔用內存上,靜態方法和實例方法是同樣的,在類型第一次被使用時加載。調用的速度基本上沒有差異。
二、你們都覺得「 靜態方法在堆上分配內存,實例方法在堆棧上
事實上全部的方法都不可能在堆或者堆棧上分配內存,方法做爲代碼是被加載到特殊的代碼內存區域,這個內存區域是不可寫的。
方法佔不佔用更多內存,和它是否是static沒什麼關係。  
  由於字段是用來存儲每一個實例對象的信息的,因此字段會佔有內存,而且由於每一個實例對象的狀態都不一致(至少不能認爲它們是一致的),因此每一個實例對象的因此字段都會在內存中有一分拷貝,也由於這樣你才能用它們來區分你如今操做的是哪一個對象。  
  但方法不同,不論有多少個實例對象,它的方法的代碼都是同樣的,因此只要有一份代碼就夠了。所以不管是static仍是non-static的方法,都只存在一份代碼,也就是隻佔用一分內存空間。  
  一樣的代碼,爲何運行起來表現卻不同?這就依賴於方法所用的數據了。主要有兩種數據來源,一種就是經過方法的參數傳進來,另外一種就是使用class的成員變量的值……
三、你們都覺得「實例方法須要先建立實例才能夠調用,比較麻煩,靜態方法不用,比較簡單
事實上若是一個方法與他所在類的實例對象無關,那麼它就應該是靜態的,而不該該把它寫成實例方法。因此全部的實例方法都與實例有關,既然與實例有關,那麼建立實例就是必然的步驟,沒有麻煩簡單一說。
固然你徹底能夠把全部的實例方法都寫成靜態的,將實例做爲參數傳入便可,通常狀況下可能不會出什麼問題。
從面向對象的角度上來講,在抉擇使用實例化方法或靜態方法時,應該根據是否該方法和實例化對象具備邏輯上的相關性,若是是就應該使用實例化對象  反之使用靜態方法。這只是從面向對象角度上來講的。
若是從線程安全、性能、兼容性上來看  也是選用實例化方法爲宜。
咱們爲何要把方法區分爲:靜態方法和實例化方法 ?
若是咱們繼續深刻研究的話,就要脫離技術談理論了。早期的結構化編程,幾乎全部的方法都是「靜態方法」,引入實例化方法概念是面向對象概念出現之後的事情了,區分靜態方法和實例化方法不能單單從性能上去理解,建立c++,java,c#這樣面嚮對象語言的大師引入實例化方法必定不是要解決什麼性能、內存的問題,而是爲了讓開發更加模式化、面向對象化。這樣說的話,靜態方法和實例化方式的區分是爲了解決模式的問題。
拿別人一個例子說事:
 好比說「人」這個類,每一個人都有姓名、年齡、性別、身高等,這些屬性就應該是非靜態的,由於每一個人都的這些屬性都不相同;但人在生物學上屬於哪一個門哪一個綱哪一個目等,這個屬性是屬於整我的類,因此就應該是靜態的——它不依賴與某個特定的人,不會有某我的是「脊椎動物門哺乳動物綱靈長目」而某我的倒是「偶蹄目」的。
相關文章
相關標籤/搜索