iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 13
0
Modern Web

ASP.NET Web Form 入門30天系列 第 13

[ASP.NET] [C#] 物件導向 - 十分鐘聽我說 類別 (二)

本篇擷取重點:

  • 更深入的探討方法
    • 一般方法
    • 靜態方法
    • 建構函式方法

一、更深入的探討方法 - 一般方法、類別方法和建構函式

從上一篇文章中,我們大概能理解類別比較算是一個範本,裡面定義好該有的屬性和方法,可是其中方法又大概可以分為一般的方法、靜態方法和建構函式三種,而這就是本篇文章的重點。


為了方便從網頁上看出結果輸出差異,故先在(.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(新)

網頁顯示:
https://ithelp.ithome.com.tw/upload/images/20190914/20120056vZjhsFiaS3.jpg


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(新)

網頁顯示:
https://ithelp.ithome.com.tw/upload/images/20190914/20120056UPVazvz85M.jpg

==================================================================
貼心小補充:

  1. 非靜態方法只能以實體叫用,所以靜態類別內無法有非靜態方法(靜態類別內一切都是靜態的)。

  1. 既然靜態類別這麼方便,為什麼不建議大量使用static呢? 下方列出幾個原因:
  • 無謂地佔住記憶體過久
  • 相同的記憶空間造成無法獨立進行單元測試
  • 無法享用物件導向設計的好處(繼承的重用與擴充、介面的可抽換性、多型的擴充性)

不過,在實務上,有時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://ithelp.ithome.com.tw/upload/images/20190914/20120056peqU8aINgG.jpg

參考資料:
https://noob.tw/java-oop/
http://dog0416.blogspot.com/2017/11/cvisual-studio-class-and-object.html


明日(9/15)預定探討課題為

  • 物件


上一篇
[ASP.NET] [C#] 物件導向 - 十分鐘聽我說 類別 (一)
下一篇
[ASP.NET] [C#] 物件導向 - 物件能做的事,比你想的還要多
系列文
ASP.NET Web Form 入門30天30

1 則留言

2
小朱
iT邦新手 4 級 ‧ 2019-09-14 23:23:58

對於static的用法,我自己有另一套看法,static的資料變數應該限制 (因為它會一直存留在記憶體沒有錯),但static的方法不能使用就挺奇怪的,因為實務上就算用介面、多型去分割好了,總是會有一些功能用static的方法反而會比一堆的介面和多型易用,或許單就可測試性來看是對的,但這世界上的程式不是只有針對可測試性而寫,不過static可以由團隊的政策或風格來限制是可以的。

至於你提到的問題,因為你的 ID 是 static,當然不能用物件變數來存取,這點在類別內或外皆然。

了解,果然我還沒讀通哈哈哈,謝謝S大的回覆

p.s. 不是static的方法"不能使用"啦,是"為何不盡量使用",可能寫得太饒舌了,我來修正一下語法XDD

小朱 iT邦新手 4 級 ‧ 2019-09-15 01:36:55 檢舉

即便是盡量不使用也是有原則的,建議再多找些文章來看。

好的!!

我要留言

立即登入留言