本篇擷取重點:
一、更深入的探討方法 - 一般方法、類別方法和建構函式
從上一篇文章中,我們大概能理解類別比較算是一個範本,裡面定義好該有的屬性和方法,可是其中方法又大概可以分為一般的方法、靜態方法和建構函式三種,而這就是本篇文章的重點。
為了方便從網頁上看出結果輸出差異,故先在(.aspx)設置一個Label作輸出接口,如下圖
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="message" runat="server" Text=""></asp:Label>
</div>
</form>
</body>
1. 一般方法
新建一個類別NoStaticClass,內含整數欄位 _id、整數屬性ID 及免回傳值的方法Method()
public class NoStaticClass
{
private int _id; //欄位
public int ID //屬性
{
get { return _id; } //讀取
set { _id = value; } //存入,Value為預設丟入值的變數名稱
}
public void Method() //方法
{
ID = ID * 10;
}
}
當完類別建立後,除非是靜態類別(Static),否則我們都必須要初始化(new)執行個體(物件),讓它執行我們的計劃。
message.Text += "一般方法示範區<br>";
NoStaticClass noStaticClass = new NoStaticClass(); //初始化物件(noStaticClass)
noStaticClass.ID = 1; //宣告物件(noStaticClass)之屬性ID為1
int NoStaticClassID = noStaticClass.ID;
message.Text += NoStaticClassID + "<br>"; //印出,物件(noStaticClass)之屬性ID(舊)
noStaticClass.Method(); //執行方法(Method),原ID*10,即1*10=10
message.Text += noStaticClass.ID + "<br><hr>"; //印出,物件(noStaticClass)之屬性ID(新)
網頁顯示:
2. 靜態方法/類別方法
新建一個靜態(static)的類別StaticClass,內含靜態(static)的整數欄位 _id、整數屬性ID 及免回傳值的靜態方法Method()
public static class StaticClass
{
private static int _id; //欄位
public static int ID //屬性
{
get { return _id; }
set { _id = value; }
}
public static void Method() //靜態方法
{
ID = ID * 10;
}
}
static 基本上的使用與一般方法相同,不同之處的就是它不需使用 new 關鍵字來初始化類別類型的物件
但也可從下方程式碼中,注意到不論是屬性或者是方法都是存在類別層級(類別(StaticClass))中
message.Text += "類別方法示範區<br>";
StaticClass.ID = 2; //宣告"類別"(StaticClass)之屬性ID為2
int StaticClassID = StaticClass.ID;
message.Text += StaticClassID + "<br>"; //印出,"類別"(StaticClass)之屬性ID(舊)
StaticClass.Method(); //執行"類別"(StaticClass)之方法(Method),原ID*10,即2*10=20
message.Text += StaticClass.ID + "<br><hr>"; //印出,"類別"(StaticClass)之屬性ID(新)
網頁顯示:
==================================================================
貼心小補充:
不過,在實務上,有時static方法反而會比一堆的介面和多型容易使用,所以static方法的使用時機判斷,不應單該從記憶體耗用或可測性層面考量而要回歸意義層面考量。
因為,如果從物件導向封裝的角度出發,靜態方法及非靜態方法其意義有明顯的差異:
例如一個公開類別的公開靜態方法跟公開非靜態方法,
公開類別的公開靜態方法,即使不屬於此類別也能叫用,因為都是公開的。
公開類別的公開非靜態方法,卻只能是屬於此類別的實體才能叫用。
下方舉個例子來幫助理解,
例如一個公開類別名叫"我",有個方法叫"叫我起床"
如果他是靜態方法,那真棒,誰都可以叫我起床
如果他是非靜態方法,那有點糟,只有我可以叫我自己起床,沒人幫的了我QQ
所以程式的編寫沒有一定的定律或最好的寫法,只有最適合當下情況的作法。
參考資料:
https://dotblogs.com.tw/im_sqz777/2017/11/14/235408
http://weisnote.blogspot.com/2012/08/static.html (內有static及非static使用時機比喻,推薦)
==================================================================
3. 建構函式
與方法類似,但當您在類別裡面放建構函式,就可以在初始化物件的時候,把所有屬性一次給完。
新建一個類別ConstructorClass,內含靜態的整數欄位 _id、靜態的整數屬性ID 及建構式方法ConstructorClass()。
public class ConstructorClass
{
private int _id; //欄位
public int ID //屬性
{
get { return _id; }
set { _id = value; }
}
public ConstructorClass(int id) //建構函式
{
ID = id * 10;
}
}
比較特別的是建構函式的名稱必定需與類別名稱相同。
message.Text += "建構式方法示範區<br>";
ConstructorClass constructorClass = new ConstructorClass(3);
//初始化物件(constructorClass),並同時宣告物件(constructorClass)之屬性ID為3*10=30
int ConstructorClassID = constructorClass.ID;
message.Text += constructorClassID + "<br><hr>"; //印出,物件(constructorClass)之屬性ID(新)
網頁顯示:
參考資料:
https://noob.tw/java-oop/
http://dog0416.blogspot.com/2017/11/cvisual-studio-class-and-object.html
明日(9/15)預定探討課題為
對於static的用法,我自己有另一套看法,static的資料變數應該限制 (因為它會一直存留在記憶體沒有錯),但static的方法不能使用就挺奇怪的,因為實務上就算用介面、多型去分割好了,總是會有一些功能用static的方法反而會比一堆的介面和多型易用,或許單就可測試性來看是對的,但這世界上的程式不是只有針對可測試性而寫,不過static可以由團隊的政策或風格來限制是可以的。
至於你提到的問題,因為你的 ID 是 static,當然不能用物件變數來存取,這點在類別內或外皆然。
了解,果然我還沒讀通哈哈哈,謝謝S大的回覆
p.s. 不是static的方法"不能使用"啦,是"為何不盡量使用",可能寫得太饒舌了,我來修正一下語法XDD
即便是盡量不使用也是有原則的,建議再多找些文章來看。
好的!!