yzx99

导航

 
之前就有说过构造函数的重载了,并且对重载、重构、方法重写这三个易混淆的概念。这一次看到的是重载的一般概念,对于一般函数甚至操作符都有重载,而不只是构造函数。
重载的使用场合有:
1.相同(或相近)功能,相同参数,不同类型的函数不必单独命名。这一点应该说是编程语言本身的限制造成的,如果编程语言能够自动转换各种不同类型,我们根本不必为不同类型的函数独立编程。
如:我们要一个交换两个变量的函数,

using System;

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方式。实际的编程一定是写一个完整参数的函数,然后缺胳膊少腿的重载函数在内部补全默认参数后,再调用完整参数的函数,但冥冥之中,总感觉更好的形式不应该是这样的。

即使到现在,我还不能接受重载的意义,但重载的其它内容还是要继续测试下去的。

注意事项中有提到四点:一是入口参数类型要不同,而不是入口参数要不同,如以下代码将会编译不通过:

using System;

public class m
{
 
static void Main()
 
{
  point p
=new point();
  p.showxy(
1221);
 }

}


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环境中,自动提示功能正常,并且编译也正常。

using System;

public class m
{
 
static void Main()
 
{
  point p
=new point();
  p.showxy(
1221);
 }

}


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; }

}
第三点:“调用不确定问题”
using System;

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

系统是会自动按着默认的规则进行类型转换,基本原则是从低精度的可以转为高精度。如果是以下的代码,对于编程人员来说不一定是个好习惯,但对于编译器来说,怎么不提个醒?

using System;

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 ); }
}
第四点:重载用到父类与子类时,与方法重写有什么区别?
以下代码执行正常:
using System;

public class m
{
 
static void Main()
 
{
  point p
=new point();
  p.showxy(
12);
  rectpoint rp
=new rectpoint();
  rp.showxy(
1215);
 }

}


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); }
}
对于showxy,这算是重载,还是重写?

posted on 2008-06-09 23:42  yzx99  阅读(761)  评论(0编辑  收藏  举报