程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 1.方法的重載--【編譯時的多態】,重載--編譯多態

1.方法的重載--【編譯時的多態】,重載--編譯多態

編輯:C#入門知識

1.方法的重載--【編譯時的多態】,重載--編譯多態


講到方法的重載,概念性的東西,請看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");
        }   

 

 

 

總結:方法的調用,是根據參數來的。

 

 

所以我們最後總結一下:

  1. C# recognizes the method by its parameters and not only by its name.【方法重載的時候,C#辨識方法是通過參數,不是方法名】
  2. 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.【如果方法名稱一樣的話,方法的返回值類型,或者方法參數的類型從來都不是方法簽名的一部分】
  3. Modifiers such as static are not considered as part of the method signature.【訪問修飾符例如static不是方法簽名的一部分】
  4. 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.【方法的簽名,是由方法的名稱,參數的個數和參數的形式決定的,方法的返回值不是方法簽名的一部分,兩個方法不能有相同的簽名,非成員之間也不能有相同的名稱。】
  5. Parameter names should be unique. And also we cannot have a parameter name and a declared variable name in the same function.【參數的名字必須是唯一的,方法中已經有了一個參數,就不能在方法內在聲明相同的名稱的局部變量】
  6. 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.
  7. 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參數必須是方法參數列表的最後一個】
  8. C# is very smart to recognize if the penultimate argument and the params have the same data type.【C#可以自動判斷參數列表中的數據類型】
  9. A Parameter Array must be a single dimensional array.【參數數組必須是一維數組】

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved