重载的使用场合有:
1.相同(或相近)功能,相同参数,不同类型的函数不必单独命名。这一点应该说是编程语言本身的限制造成的,如果编程语言能够自动转换各种不同类型,我们根本不必为不同类型的函数独立编程。
如:我们要一个交换两个变量的函数,
public class m
{
static void Main()
{
int x=12;
int y=15;
HY.swap(ref x, ref y);
Console.WriteLine("x=" + x + "; y=" + y);
}
}
static class HY
{
public static void swap(ref int a, ref int b)
{ int t=a;
a=b;
b=t;
}
}
如果前面的x与y改为
float x=12;
float y=15;
编译时,系统就会提示:
p.cs(9,3): error CS1502: 与“HY.swap(ref int, ref
int)”最匹配的重载方法具有一些无效参数
p.cs(9,15): error CS1503: 参数“1”: 无法从“ref float”转换为“ref int”
p.cs(9,22): error CS1503: 参数“2”: 无法从“ref float”转换为“ref int”
目前,我们的做法要么增加一个新的函数名(如swap_float),要么我们用重载,只让函数名不增加,但函数还是要写的。
以后,我试着找一下有没有可能函数只要写一个,就能在性能不明显降低的情况下适应各种情况。
2.相同(或相近)功能,参数个数不同。《大话设计模式》中的例子,一只小狗不是一定要有姓名之后才能诞生的,可以先诞生,让它的名字为“无名”,然后在合适的时候给它取个名字。虽然这是对构造函数而言,但对一般的函数也是有类似的情况,这时也为了不增加函数名称,使用重载。
但如果这样用重载导致代码重新再写过一遍,我感觉划不来,还不如宁可使用VB的optional方式。实际的编程一定是写一个完整参数的函数,然后缺胳膊少腿的重载函数在内部补全默认参数后,再调用完整参数的函数,但冥冥之中,总感觉更好的形式不应该是这样的。
即使到现在,我还不能接受重载的意义,但重载的其它内容还是要继续测试下去的。
注意事项中有提到四点:一是入口参数类型要不同,而不是入口参数要不同,如以下代码将会编译不通过:
public class m
{
static void Main()
{
point p=new point();
p.showxy(12, 21);
}
}
class point
{
public void showxy(int x, int y)
{ Console.WriteLine("x=" + x + "; y=" + y); }
public void showxy(int y, int x)
{ Console.WriteLine("x=" + x + "; y=" + y); }
}
编译器提示:
p.cs(16,14): error CS0111:
类型“point”已定义了一个名为“showxy”的具有相同参数类型的成员
p.cs(14,14): (与前一个错误相关的符号位置)
第二个showxy本想让如果进入的参数是颠倒的,在代码中把它调正。但对于“p.showxy(12, 21);”,即使是人,都不知道到底是不是颠倒了xy。
第二点,重载的函数返回值可以不相同。不知道是以前的C++不允许相同,还是书上写错了,反正我手头上一本书是说重载的函数之间返回值必须相同,但我输入如下代码后,在VS2005环境中,自动提示功能正常,并且编译也正常。
public class m
{
static void Main()
{
point p=new point();
p.showxy(12, 21);
}
}
class point
{
public void showxy(int x)
{ Console.WriteLine("x=" + x ); }
public int showxy(int x, int y)
{ Console.WriteLine("x=" + x + "; y=" + y);
return 0; }
}
public class m
{
static void Main()
{
point p=new point();
p.showxy(3.8);
}
}
class point
{
public void showxy(float x)
{ Console.WriteLine("x1=" + x ); }
public void showxy(double x)
{ Console.WriteLine("x2=" + x ); }
}
执行结果会是什么?
标准答案:x2=3.8
系统是会自动按着默认的规则进行类型转换,基本原则是从低精度的可以转为高精度。如果是以下的代码,对于编程人员来说不一定是个好习惯,但对于编译器来说,怎么不提个醒?
public class m
{
static void Main()
{
point p=new point();
int x=12;
p.showxy(x);
}
}
class point
{
public void showxy(float x)
{ Console.WriteLine("x1=" + x ); }
public void showxy(double x)
{ Console.WriteLine("x2=" + x ); }
}
以下代码执行正常:
public class m
{
static void Main()
{
point p=new point();
p.showxy(12);
rectpoint rp=new rectpoint();
rp.showxy(12, 15);
}
}
class point
{
public void showxy(int x)
{ Console.WriteLine("x=" + x ); }
}
class rectpoint:point
{
public void showxy(int x, int y)
{ Console.WriteLine("rect:x=" + x + ";y=" + y); }
}