在C#或其他面向对象语言中,重写、重载和隐藏的机制,是设计高可扩展性的面向对象程序的基础。
(1)重写和隐藏
重写(Override)是指子类用Override关键字重新实现定义在基类中的虚方法,并且在实际运行时根据对象类型来调用相应的方法。.
隐藏则是指子类用new关键字重新实现定义在基类中的方法,但在实际运行时只能根据引用来调用相应的方法。
以下的代码说明了重写和隐藏的机制以及它们的区别:
public class Program
{
public static void Main(string[] args)
{
// 测试二者的功能
OverrideBase ob = new OverrideBase();
NewBase nb = new NewBase();
Console.WriteLine(ob.ToString() + ":" + ob.GetString());
Console.WriteLine(nb.ToString() + ":" + nb.GetString());
Console.WriteLine();
// 测试二者的区别
BaseClass obc = ob as BaseClass;
BaseClass nbc = nb as BaseClass;
Console.WriteLine(obc.ToString() + ":" + obc.GetString());
Console.WriteLine(nbc.ToString() + ":" + nbc.GetString());
Console.ReadKey();
}
}
// Base class
public class BaseClass
{
public virtual string GetString()
{
return "我是基类";
}
}
// Override
public class OverrideBase : BaseClass
{
public override string GetString()
{
return "我重写了基类";
}
}
// Hide
public class NewBase : BaseClass
{
public new virtual string GetString()
{
return "我隐藏了基类";
}
}
以上代码的运行结果如下图所示:
我们可以看到:当通过基类的引用去调用对象内的方法时,重写仍然能够找到定义在对象真正类型中的GetString方法,而隐藏则只调用了基类中的GetString方法。
(2)重载
重载(Overload)是拥有相同名字和返回值的方法却拥有不同的参数列表,它是实现多态的立项方案,在实际开发中也是应用得最为广泛的。常见的重载应用包括:构造方法、ToString()方法等等;
以下代码是一个简单的重载示例:
public class OverLoad
{
private string text = "我是一个字符串";
// 无参数版本
public string PrintText()
{
return this.text;
}
// 两个int参数的重载版本
public string PrintText(int start, int end)
{
return this.text.Substring(start, end - start);
}
// 一个char参数的重载版本
public string PrintText(char fill)
{
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
sb.Append(c);
sb.Append(fill);
}
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
}
public class Program
{
public static void Main(string[] args)
{
OverLoad ol = new OverLoad();
// 传入不同参数,PrintText的不同重载版本被调用
Console.WriteLine(ol.PrintText());
Console.WriteLine(ol.PrintText(2,4));
Console.WriteLine(ol.PrintText('/'));
Console.ReadKey();
}
}
运行结果如下图所示: