講到方法的重載,概念性的東西,請看MSDN,我們還是看下例子吧:
示例一:
1.新建一個控制台程序:添加一個類【Overload】:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OOP1 { /// <summary> /// 編譯時的多態:方法的重載 /// </summary> public class Overload { /// <summary> /// 方法的簽名:包含方法的名字和參數(參數的數量和個數) /// </summary> /// <param name="a"></param> public void DisplayOverload(int a) { Console.WriteLine("DisplayOverload: "+a); } /// <summary> /// 方法的簽名:包含方法的名字和參數(參數的數量和個數) /// </summary> /// <param name="a"></param> public void DisplayOverload(string a) { Console.WriteLine("DisplayOverload: "+a); } /// <summary> /// 方法的簽名:包含方法的名字和參數(參數的數量和個數) /// </summary> /// <param name="a"></param> /// <param name="b"></param> public void DisplayOverload(string a, int b) { Console.WriteLine("DisplayOverload: "+a +b); } } }
主函數中:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OOP1 { class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.DisplayOverload(1000); overload.DisplayOverload("Hello C# Method Overload"); overload.DisplayOverload("方法的重載", 2000); Console.ReadKey(); } } }
運行程序:
階段性總結:
1.方法重載,C#是根據傳遞過去的參數,來識別該調用哪個重載方法的,而不是方法名字!
2.方法的簽名:由方法的名字和方法的參數和方法的數據類型組成!
示例二:
#region 錯誤1 :已定義了一個名為“DisplayOverload”的具有相同參數類型的成員 /// <summary> /// 方法的返回值類型不是方法簽名的一部分,所以,這兩個方法不是方法重載, /// </summary> //public void DisplayOverload() //{ // Console.WriteLine("Hello"); //} /// <summary> /// 方法的返回值類型不是方法簽名的一部分,所以,這兩個方法不是方法重載, /// </summary> //public int DisplayOverload() //{ // return 1; //} #endregion
編譯不通過,總結:方法的返回值類型,不是方法重載的一部分。
示例三:
#region 錯誤2:已定義了一個名為“DisplayOverload”的具有相同參數類型的成員 /// <summary> /// 訪問修飾符(例如:static),不是方法簽名的一部分。 /// </summary> /// <param name="a"></param> //static void DisplayOverload(int a) //{ //} /// <summary> /// 訪問修飾符(例如:static),不是方法簽名的一部分。 /// </summary> /// <param name="a"></param> //public void DisplayOverload(int a) //{ //} /// <summary> /// 訪問修飾符(例如:static),不是方法簽名的一部分。 /// </summary> /// <param name="a"></param> //public void DisplayOverload(string a) //{ //} #endregion
編譯不通過,總結:方法的訪問修飾符,例如(static等),不是方法簽名的一部分。
示例四:
上面的圖中,有三個方法,編譯的時候,兩個錯誤,這裡有點奇怪的是,我分別注釋掉,第二個方法,和第三個方法,編譯之後:都只剩下一個錯誤了。
總結:方法的簽名不僅僅包含參數的數據類型,同樣也包含參數的種類,例如ref 和out等。
所以進一步總結:方法的簽名,不僅僅由方法的名稱,參數的數量,參數的類型,還包括參數的形式組成。方法的返回值不是方法簽名的一部分。兩個方法不能有相同的簽名,並且成員之間,不能有相同的名字。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接著,講一下,編譯時的多態【方法重載】中的Params參數
一個方法,能夠被下面四種類型的參數調用:
前面說到了,方法的訪問修飾符,不是方法簽名的一部分,現在我們來聚焦討論參數數組。
方法的聲明,會在內存中,創造一個獨立的內存空間,所以:
這圖中的第一個方法,參數名重復了,第二個方法,因為方法參數中已經聲明過了。現在又在方法內聲明一個名字一樣的局部變量,也是不對的。
總結一下:參數的名字,必須是唯一的,並且在方法中,我們不能在已經有了一個參數名字,而在方法中在聲明一個相同名稱的局部變量!!!
示例五:
/// <summary> /// 定義一個私有字段 /// </summary> private string name = "daniel"; public void Display() {
Dispaly2(ref name, ref name);
Console.WriteLine(name);
} private void Dispaly2(ref string x, ref string y) { Console.WriteLine(name); x = "Mike 1"; Console.WriteLine(name); y = "Mike 2"; Console.WriteLine(name); name = "Mike 3"; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OOP1 { class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } } }
因為是引用傳遞,所以在方法內改變字段的值,原來的name字段值也改變了,(指針指向的地址是一樣的。)
示例六:
public void Display() { DisplayOverload(300); DisplayOverload(400, "Daniel", "深圳寶安"); DisplayOverload(800, "哇哈哈"); } public void DisplayOverload(int a, params string[] parameterArray) { foreach (var item in parameterArray) { Console.WriteLine(item+" "+a); } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OOP1 { class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } } }
總結:使用參數數組,可以想傳遞多少個參數就傳遞多少個。參數數組必須是參數列表的最後一個,例如:
示例七:
public void Display() { DisplayOverload(100, 200, 300); DisplayOverload(200, 100); DisplayOverload(200); } private void DisplayOverload(int a, params int[] parameterArray) { foreach (var i in parameterArray) Console.WriteLine(i + " " + a); }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OOP1 { class Program { static void Main(string[] args) { Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } } }
總結:C#是非常智能的,可以識別出,第二個參數是否是相同的類型(和第一個參數類型int對比)
示例八;
總結:參數數組必須是一維數組。
示例九:
public void Display() { string[] names = { "Akhil", "Ekta", "Arsh" }; DisplayOverload(3, names); } private void DisplayOverload(int a, params string[] parameterArray) { foreach (var s in parameterArray) Console.WriteLine(s + " " + a); }
總結:我們允許,傳遞數組到參數數組中,而不是單個的string字符串。
示例十:
總結,第三個參數,是多余的。
示例十一:
public void Display() { int[] numbers = { 10, 20, 30 }; DisplayOverload(40, numbers); Console.WriteLine(numbers[1]); } private void DisplayOverload(int a, params int[] parameterArray) { parameterArray[1] = 1000; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OOP1 { class Program { static void Main(string[] args) { //Overload overload = new Overload(); //overload.DisplayOverload(1000); //overload.DisplayOverload("Hello C# Method Overload"); //overload.DisplayOverload("方法的重載", 2000); //Console.ReadKey(); Overload overload = new Overload(); overload.Display(); Console.ReadKey(); } } }
總結:因為數組是引用類型,不管是什麼類型的數組,所以numbers[1]變成了1000.
示例十二:
public void Display() { int number = 102; DisplayOverload(200, 1000, number, 200); Console.WriteLine(number); } private void DisplayOverload(int a, params int[] parameterArray) { parameterArray[1] = 3000; }
因為number是值類型,在方法調用前後,值還是不變。
示例十四:
public void Display() { DisplayOverload(200); DisplayOverload(200, 300); DisplayOverload(200, 300, 500, 600); } private void DisplayOverload(int x, int y) { Console.WriteLine("The two integers " + x + " " + y); } private void DisplayOverload(params int[] parameterArray) { Console.WriteLine("parameterArray"); }
總結:方法的調用,是根據參數來的。
所以我們最後總結一下: