函数重载有哪些主要优点,一定要重载吗

解决方案 »

  1.   

    哈哈,问这问题的都是新手啊.   什么叫多态? 懂这个吗?分太少,做人要厚道演示代码在这里:  http://www.vjsdn.com/bbs/bbsTopicDetails.aspx?pid=398
      

  2.   

    我认为重载的优点并不是为了少写重复代码,而是为了以更清晰的方式描述类的方法。类的方法代表着一个功能,而同一个功能,具有不同的参数时表现也有差异(一般只是略有差异),这就要重载了,而对外的函数名仍然是一个。不重载你就得起两个不同的函数名,而对于同一功能而言,多个名字会引起混乱。例如一个方法ToString把一个字符串数组依次组合成一个大字符串。

    str(0)="A";
    str(1)="B";
    str(2)="C";一个方法为ToString()
    返回值为"A,B,C",即缺省以逗号做间隔一个重载方法为ToString(String splitString)
    可以由用户指定间隔符比如调用ToString(" ")则输出"A B C"如果不使用重载你就得起两个函数名了。楼主设计一些类就能理解重载的必要性了,几乎是必然使用的。
      

  3.   

    这里有一个初学者经常混淆的概念。覆盖(override)和重载(overload)。上面说了,覆盖是指子类重新定义父类的虚函数的做法。而重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。其实,重载的概念并不属于“面向对象编程”,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的(记住:是静态)。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!真正和多态相关的是“覆盖”。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态(记住:是动态!)的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚邦定)。
      

  4.   


    函数的重载是静态的多态
    而函数的重写Virtual/Override则是一种动态的多态
      

  5.   

    拿个很老的例子来说
    Add方法
    public string Add(params string[] str);
    public int Add(int a, int b);
    public int Add(ref int a, int b);
    public double Add(double a, double b);
    这样在调用的时候我们都是Call的Add方法,但是却根据参数的不同而产生不同的行为。
    对于开发者来说,也不用去记那么多不同的方法名,一个方法名,不同参数,实现不同即可。
      

  6.   


    既然楼上的大哥说到了早绑定,晚绑定,那么我也来凑一脚,说说自己的理解:
    上代码:
    Scenairo 1:  class Parent
        { 
            public void Call()
            {
                Console.WriteLine("Call of Parent");
            }
        }    class Child:Parent
        {
            public void Call()
            {
                Console.WriteLine("Call of Child");
            }
        }    class test
        {
            public static void Main()
            {
                Parent child = new Child();
                a.Call();
                Console.ReadKey();        }        
        }输出Call of Parent,这里child中的Call方法会有一个警告,要加new,加上之后输出结果一样Scenario 2:class Parent
        { 
            public virtual void Call()
            {
                Console.WriteLine("Call of Parent");
            }
        }    class Child:Parent
        {
            public void Call()
            {
                Console.WriteLine("Call of Child");
            }
        }    class test
        {
            public static void Main()
            {
                Parent child = new Child();
                child.Call();
                Console.ReadKey();        }        
        }虽然Parent中的Call方法改成了虚方法,但是输出结果
    仍然是Call of Parent,child中的Call方法还是会有一个警告,要加new,加上之后输出结果一样。Scenario 3  class Parent
        { 
            public virtual void Call()
            {
                Console.WriteLine("Call of Parent");
            }
        }    class Child:Parent
        {
            public override void Call()
            {
                Console.WriteLine("Call of Child");
            }
        }    class test
        {
            public static void Main()
            {
                Parent child = new Child();
                child.Call();
                Console.ReadKey();        }        
        }父类方法中Virtual,子类方法中Override
    输出Call of Child
    上述的三种情况: 1和2都是早绑定,而3则是晚绑定
    因为在实例话子类的时候,其引用都是父类,那么C#会判断,如果调用的方法在父类和子类中有了
    Virtual/Override对的话,那么才会在运行时判断,实例到底是什么,此处3情况,实例是子类的,所以去调用了子类Call的方法
    而对于1,2情况来说,应为没有Virtual/Override对,即使是虚方法,编译器也不会管你,它在编译的时候只会去看引用的类型,此处,因为实例化时的引用类型是父类型,所以方法指针直接指向父类方法,这个就叫做早绑定