5-2 類別與物件

類別是C#最基礎的型別。
除了之前學過的數值型別,如 int、float、string……等等,我們還會自定義自己需要的型別。

打個比方說,我們需要描述「寵物」的資料。我們可能會寫成如下的類別:

類別主要是由以下項目所組成:
● 欄位:只是個專有名詞,實際上就是隸屬於該類別的變數。
● 建構函式:建立該類別的物件或是初始化的行為。
● 方法:類別可以執行的行為。
● 完成項:永久捨棄該類別物件之前要執行的行為。使用者無法呼叫,而是由語言底層呼叫。
(很少用到的功能,但是需要知道有這個東西存在)

類別的存取修飾詞

類別的存取修飾詞只能是 public 或 internal,預設層級為 internal。
但巢狀類別(類別內的類別)可以使用全部的存取修飾詞,預設層級為 private。

P.S. 通常不會在這時寫給新手看的巢狀類別,我在這時寫出來了。
巢狀類別目前還不用很清楚知道怎麼用。
主要是讓你開始覺得「可以用的層級」與「預設層級」有點難記。
另外,針對每個東西可以使用的修飾詞與預設值,可是有 2 張表需要記憶(非巢狀與巢狀)。

這裡給個建議:不要死記,大概知道即可,程式寫久就會記起來了。
不管預設層級是什麼,永遠要寫下存取修飾詞。
寫下來,讓其它的工程師和自己都清楚的知道變數與方法的存取層級。

建構函式

類別本身只是描述其「實際形體」的資訊,真正在運作的是那些「實際形體」。
我們通常把這些「實際形體」叫做物件,又稱為執行個體

我們等等再來談物件的概念,現在先來了解建構函式。

要產生類別的實體,必須使用 new 運算子來呼叫類別的建構函式。
建構函式以存取修飾詞起頭,如果沒有寫修飾詞,就會是預設值 private。
沒有回傳型別,因為回傳型別一定是該類別。
接著方法名稱與類別名稱相同
可以回到上面看看Pet的建構函式。

以上面的Pet為例,我們要產生一個 Pet 的實體。
先宣告變數,型別為 Pet,名稱為 pet1。
pet1 的值是我們要產生的 Pet 實體,因此使用 new 加上 Pet 的建構函式,並填入所需的參數。

類別可以有不只一個建構函式,當然參數內容要不一樣,不然 C# 分不出來你要呼叫哪個方法。

除此之外,如果完全不寫建構函式,底層會自動幫你預設建構函式為無參數、無行為的方法。

物件

我們用簡單的例子解釋物件這個詞的概念。
以上面的 Pet 類別為例,假設你有 2 隻寵物,姑且不管它們是什麼動物,一隻叫 Dudu,一隻叫 Mew。
正常來說,你應該會把它們當作不同的個體來看待。

就這樣,這就是物件的概念!

我們轉換到程式的概念,用 Pet 的建構函式建立 2 個 Pet 物件。

我們會說,pet1 與 pet2 是不同的物件。pet1 代表名字叫做 Dudu 的寵物;pet2 代表名字叫做 Mew 的寵物。
話說回來,從使用new的方法得知,它們甚至連記憶體的位置都不一樣,當然是不同的資料囉!

但是,接續這個例子,假設出現了第 3 隻寵物,是其它飼主養的,名字也叫 Dudu。

即使名字一樣,你也應該會覺得這 2 隻 Dudu 是不同個體。
再極端一點,即使品種相同、毛色相同、大小相同、叫聲相同……等等,你也應該會覺得這 2 隻 Dudu 是不同個體。

所以,即使資料相同,pet1 與 pet3 仍然是不同的物件。順帶一提,記憶體的位置也不一樣。

完成項

完成項,是在該實體的記憶體被回收前執行的方法,又稱為解構函式。
完成項是用來自行釋放資源的,例如:關閉正在編輯的文字檔案。

C#底層會自行管理記憶體的回收。
如果你原本使用的記憶體區塊,然後隨著程式運行,可能會出現沒有被任何其他物件使用的物件。
這些物件會被管理機制回收掉 (可以想成破壞掉),這時候就會看看有沒有完成項需要執行。

● 完成項只能有一個,且必定是 ~ 符號加上類別名稱的無參數方法。
● 使用者無法自行呼叫完成項,這是由底層來管理的。
● 使用者無法預測完成項何時被呼叫,這是由底層來管理的。
● 如果你不需要完成項,就不要寫空的完成項,會造成不必要的效能損耗。