講到方法的重載,概念性的東西,請看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參數
一個方法,能夠被下面四種類型的參數調用:
- 值類型的參數【By Value】
- 引用類型的參數【By reference】
- 輸出參數【output參數】
- 參數數組【parameter arrays】
前面說到了,方法的訪問修飾符,不是方法簽名的一部分,現在我們來聚焦討論參數數組。
方法的聲明,會在內存中,創造一個獨立的內存空間,所以:
這圖中的第一個方法,參數名重復了,第二個方法,因為方法參數中已經聲明過了。現在又在方法內聲明一個名字一樣的局部變量,也是不對的。
總結一下:參數的名字,必須是唯一的,并且在方法中,我們不能在已經有了一個參數名字,而在方法中在聲明一個相同名稱的局部變量!!!
示例五:
/// <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");
}
總結:方法的調用,是根據參數來的。
所以我們最后總結一下:
- C# recognizes the method by its parameters and not only by its name.【方法重載的時候,C#辨識方法是通過參數,不是方法名】
- The return value/parameter type of a method is never the part of method signature if the names of the methods are the same. So this is not polymorphism.【如果方法名稱一樣的話,方法的返回值類型,或者方法參數的類型從來都不是方法簽名的一部分】
- Modifiers such as static are not considered as part of the method signature.【訪問修飾符例如static不是方法簽名的一部分】
- The signature of a method consists of its name, number and types of its formal parameters. The return type of a function is not part of the signature. Two methods cannot have the same signature and also non-members cannot have the same name as members.【方法的簽名,是由方法的名稱,參數的個數和參數的形式決定的,方法的返回值不是方法簽名的一部分,兩個方法不能有相同的簽名,非成員之間也不能有相同的名稱。】
- Parameter names should be unique. And also we cannot have a parameter name and a declared variable name in the same function.【參數的名字必須是唯一的,方法中已經有了一個參數,就不能在方法內在聲明相同的名稱的局部變量】
- In case of by value, the value of the variable is ed and in the case of ref and out, the address of the reference is ed.
- This params keyword can only be applied to the last argument of the method. So the n number of parameters can only be at the end.【parmas參數必須是方法參數列表的最后一個】
- C# is very smart to recognize if the penultimate argument and the params have the same data type.【C#可以自動判斷參數列表中的數據類型】
- A Parameter Array must be a single dimensional array.【參數數組必須是一維數組】
文章列表