不學 JAVA 換學 C# 之覺得心累 - L1:ch7 方法
前言
方法 (Method) 是一組封裝的程式碼,用於執行特定的任務或邏輯。C# 中的方法具有靈活性和可重用性,使得程式更易於管理和維護。
特點:
- 可以有任意數量的參數與回傳值。
- 內部的實作對外部是隱藏的,僅提供接口給使用者呼叫。
- 可以重複使用,避免程式碼冗長與重複。
基本結構
每個方法都包含以下幾個部分:
- 存取修飾詞 (Accessibility Modifier):決定方法的存取範圍,例:
public
或private
。 - 靜態修飾詞 (Static Modifier):標記方法是靜態方法,或是需要實例化物件才能使用。
- 回傳型態 (Return Type):指定方法的回傳值類型。如果不需要回傳值,使用
void
。如果需要有回傳值,除了指定回傳型態,方法內還需要用return
回傳數值,且數值的型態必須跟定義的回傳型態一致。 - 方法名稱 (Method Name):方法的名稱。
- 參數列表 (Parameter List):接收外部傳入的參數,參數間用逗號分隔。參數型態必須明確列出,例如
int
、string
,以確保方法簽章的清晰性和正確性。 - 方法體 (Body):封裝的程式碼邏輯區塊。
1 | // 存取修飾詞:public, 回傳型態:int, 方法名稱:Add, 參數列表:(int x, int y) |
簽章 (Signature)
通常指方法的名稱、參數的型態、個數與順序,以及回傳值的型態。
它可以視為方法的唯一標識,用來區分不同的方法。例如,具有相同名稱但參數型態、個數與順序不同的方法會被視為不同的方法,這被稱為多載 (Overloading)。
使用、呼叫方法
1 | 方法名稱(傳入的參數列表); |
呼叫時
- 傳入的參數的數量與類型需要與定義方法時的簽章一致。
- 需要保留回傳值時,指派給某個變數。
範例
1 | // 定義方法 |
- 呼叫方法:
Add(1, 2)
是對Add
方法的一次呼叫。1
和2
是我們提供給Add
方法的實際參數 (Arguments)。方法內部的x
和y
是對應的形式參數 (Parameters),它們分別接收1
和2
的值。方法執行時,會將這兩個數字相加,指派給變數total
,然後回傳total
的值。total
的型態必須是int
,因為必須跟 line 2 定義的回傳型態一致。 - 回傳值指派給某個變數:
Add
方法的回傳型態是int
,所以它會將計算結果total
的值,也就是3
回傳給呼叫它的程式碼。這裡的return total;
將計算結果回傳,而 line 9 將回傳結果指派給int sum
。
存取修飾詞
類別 (class) 成員有方法 (method)、屬性 (property) 或欄位 (field)。而存取修飾詞是用來控制類別成員的可見性和存取範圍。目前先知道 public
和 private
就好。
public
修飾詞
使用 public
宣告的成員可以在程式的任何地方被存取,無論是同一個類別內、還是不同類別,甚至不同的命名空間。因此,需要讓其他類別或外部程式使用該成員時,就用 public
。
private
修飾詞
使用 private
宣告的成員只能在同一個類別內存取,其他類別無法直接使用。因此,該成員只用於內部邏輯,而不需要對外暴露時,就用 private
。
靜態修飾詞
靜態修飾詞和類別 class 有密切的關係,如果暫時看不懂,了解完類別再回來這看。
如果方法跟各別物件實例沒有關係,就用靜態方法,否則用非靜態方法。
非靜態方法
非靜態方法屬於物件,必須透過實例化物件來呼叫。使用物件名稱呼叫。
1 | 物件名稱.方法名(); |
以下方例子來說,不同的實例化物件 Person
有不同的名字。印出名字 PrintName
這個方法就會跟各別物件有關係,所以必須使用非靜態方法。
1 | public class Person |
靜態方法
靜態方法屬於類別本身,不需實例化物件即可呼叫。適合用於不依賴於物件狀態的邏輯。使用類別名稱呼叫。
1 | 類別名稱.方法名(); |
特性
- 靜態方法使用類別名稱後大家都可以呼叫,例:
Math.Max(x, y)
,Math
是 C# 內建類別,Max
是方法名。 - 靜態方法內部無法存取非靜態成員,因為非靜態成員需要具體的物件實例。
以下方例子來說,Max
方法不會依賴於不同的 Math
物件實例,直接用 Math
類別名呼叫 Max
方法。
1 | // 使用 Math 類別名稱呼叫 Max |
回傳型態和參數
無參數、無回傳值
僅執行動作而無需處理輸入或回傳結果。
1 | public void SayHello() |
有參數
適合需要輸入資料才能執行邏輯的情況。
1 | public void PrintMessage(string message) |
有回傳值
適合需要將處理結果回傳給呼叫者的情況。
1 | public int Multiply(int x, int y) |
陣列作為參數
在 C# 中,陣列作為參數傳遞時,是以複製記憶體位址的方式傳遞,但是因為實際參數 (Arguments) 和形式參數 (Parameters) 的值一樣,都是同一個記憶體位址,都指向同一個變數,這表示方法中對陣列內容的修改會影響到原始陣列,但重新指派陣列不會影響原始陣列,因為儲存的記憶體位址不一樣了。
C# 中沒有 Call/Pass by Address 這種說法,但是實際上 C# 的「陣列作為參數傳遞」就是 Call/Pass by Address,以下方的例子來說,是 copy 實際參數 arr
的位址給形式參數 numbers
,而不是 Call/Pass by Reference 取別名。請參考:值 (value)、指標 (pointer/address)、參考 (reference)。取別名的話,重新指派陣列會影響原始陣列。
對陣列內容的修改會影響原始陣列
1 | public void ModifyArray(int[] numbers) |
重新指派陣列不會影響原始陣列
1 | public void ReassignArray(int[] numbers) |
注意:
- 原始資料的影響:由於陣列是傳址,對方法內的修改會直接反映在原始資料中。
- 安全性考量:若不希望原始資料被修改,可以在傳入方法前複製陣列,避免直接影響原始資料。
1 | int[] copy = (int[])arr.Clone(); |
Main 方法
在 C# 應用程式中,Main
方法是程式的入口點,負責啟動程式執行。它具有一些特別的特性和用法。
- 唯一性:每個 C# 應用程式只能有一個
Main
方法作為程式的入口點。 - 回傳型別:
void
:不需要回傳值,適用於一般應用程式。int
:可以回傳整數值,通常用於指示應用程式的執行狀態。- 0:約定俗成的成功碼,表示執行成功,程式正常結束。
- 非 0 值:表示執行失敗或出現錯誤。
- 參數:
string[] args
:允許接收命令列參數,便於應用程式根據啟動時的參數執行不同邏輯。 - 靜態方法:
Main
方法必須是static
,因為它在沒有建立物件的情況下直接由執行環境呼叫。 - 多重定義:
Main
方法可以有多個定義,但只有一個簽章會作為執行入口點。如果有多個定義,必須手動指定入口點。
範例
基本架構
1 | using System; |
接收命令列參數
1 | using System; |
參考資料:
方法 (C# 程式設計手冊)
Main() 和命令列引數