NET面试题:简述C#中重写、重载和隐藏的概念
在大多数面向对象的语言中,都有重写、重载和隐藏的概念,这些机制是设计高可扩展性的面向对象程序的基础。读者应该做到不仅了解它们的功能、读懂包含这些概念的代码,也能进一步地运用它们设计出优美的面向对象的程序。
  所涉及的知识点
· 重写、重载和隐藏的概念
  分析问题
重写、重载和隐藏在C#中都有相应的关键字,它们是构建面向对象程序的基础。
1.重写和隐藏
重写(Override)是指子类用Override关键字重新实现定义在基类中的虚方法,并且在实际运行时根据对象类型来调用相应的方法。隐藏是指子类用new关键字重新实现定义在基类中的方法,但在实际运行时只能根据引用来调用相应的方法。代码3-20说明了重写和隐藏的机制以及它们的区别。
代码3-20  重写和隐藏:OverrideNew.cs
namespace NET.MST.Third.OverrideNew
{
    public class OverrideNew
    {
        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("\r\n");
            //重写和隐藏的区别
            Base obb = ob as Base;
            Base nbb = nb as Base;
            Console.WriteLine(obb.ToString() + ":" + obb.GetString());
            Console.WriteLine(nbb.ToString() + ":" + nbb.GetString());
            Console.Read();
        }
    }
    //基类
    class Base
    {
        public virtual string GetString()
        {
            return "我是基类";
        }
    }
    //重写
    class OverrideBase : Base
    {
        public override string GetString()
        {
            return "我重写了基类";
        }
    }
    //隐藏
    class NewBase : Base
    {
        public new virtual string GetString()
        {
            return "我隐藏了基类";
        }
    }
}
代码3-20定义了一个基类和两个子类,在基类中定义了一个虚方法:GetString(),而在两个子类中分别实现了重写和隐藏。当使用和对象类型相符的引用去调用对象内的方法时,重写和重载表现出了完全一样的特性,但当通过基类的引用去调用对象内的方法时,重写和重载的区别就出现了:重写仍然能够找到定义在对象真正类型中的GetString方法,而隐藏则只调用了基类中的GetString方法,下面是代码3-20的运行结果:
NET.MST.Third.OverrideNew.OverrideBase:我重写了基类
NET.MST.Third.OverrideNew.NewBase:我隐藏了基类
NET.MST.Third.OverrideNew.OverrideBase:我重写了基类
NET.MST.Third.OverrideNew. NewBase:我是基类
2.重载
重载(Overload)是拥有相同名字和返回值的方法拥有不同的参数列表,重载是实现多态的理想方案,而它在程序中的应用也是最为广泛的,常见的一些重载应用包括ToString方法、负责初始化类型的方法等。代码3-21是一个简单的重载的例子。
代码3-21  重载:Overload.cs
namespace NET.MST.Third.Overload
{
    public class Overload
    {
        private String text = "我是一个字符串";
        //三个方法实现了Print方法的三个重载版本
        public String Print()
        {
            return text;
        }
        // Print方法的重载版本
        public String Print(int start,int end)
        {
            return text.Substring(start, end - start);
        }
        // Print方法的重载版本
        public String Print(char fill)
        {
            StringBuilder builder = new StringBuilder();
            foreach (char c in text)
            {
                builder.Append(c);
                builder.Append(fill);
            }
            builder.Remove(builder.Length - 1, 1);
            return builder.ToString();
        }
        static void Main(string[] args)
        {
            Overload ol = new Overload();
            //传入不同的参数
            //Print的不同重载版本将被调用
            Console.WriteLine(ol.Print());
            Console.WriteLine(ol.Print(2, 4));
            Console.WriteLine(ol.Print('/'));
            Console.Read();
        }
    }
}
代码3-21在Overload类型内定义了Print方法的三个重载版本,当分别传入不同的参数时,将得到不同的结果。本质上,重载的每个版本都相当于一个方法,但是重载机制允许这些方法共享一个名字,用以实现多态的思想,下面是这段程序的运行结果:
我是一个字符串
一个
我/是/一/个/字/符/串
  答案
重写是指用Override关键字重新实现基类中的虚方法,在运行的过程中,无论通过哪个类型的引用,真正对象类型的方法将被调用。隐藏是指用new关键字重新实现基类中的方法,在运行的过程中通过引用的类型判断应该调用哪个类型的方法。重载是指多个方法共享同一个名字并且拥有相同的返回值,但是却可以拥有不同的参数列表
 

更多C#面试题,电子书,教学视频请参考"爱学网izixue"