每天学一点,每天积累一点,进步就不止一点点!PS:好记性不如烂笔头,学会总结,学会思考~~~ ----要飞翔,必须靠自己!

灰太狼的梦想

好记性不如烂笔头,学会总结,学会思考~~~

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参数

 

一个方法,能够被下面四种类型的参数调用:

  1. 值类型的参数【By Value】
  2. 引用类型的参数【By reference】
  3. 输出参数【output参数】
  4. 参数数组【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");
        }   

 

 

 

总结:方法的调用,是根据参数来的。

 

 

所以我们最后总结一下:

  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.【参数数组必须是一维数组】

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2016-08-11 13:14  灰太狼的梦想  阅读(1881)  评论(0编辑  收藏  举报