C#继承 - 为什么要使用override和virtual?

时间:2011-10-31 23:12:08

标签: c# inheritance

我已经使用C ++进行了一段时间的编程,现在我开始使用C#,但我无法理解virtualoverride个关键字。由于指针和所有与它相关的内容大部分都来自C ++,我们真的不需要它们吗?或者我错过了一些C#编程的重点。

示例:

namespace ConsoleApplication1
{
    public class Employee
    {
        public virtual void GetPayCheck()
        {
            Console.WriteLine("employee gets his pay check ");
        }

        public void Work()
        {
            Console.WriteLine("employee works ");
        }
    }
    public class Manager : Employee
    {
        public override void GetPayCheck()
        {
            Console.WriteLine("MANAGER gets his pay check ");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Employee emp = new Employee();
            Manager exec = new Manager();
            emp.Work();
            exec.Work();
            emp.GetPayCheck();
            exec.GetPayCheck();
        }
    }
}

即使我省略虚拟或覆盖关键字(或两者),我仍然得到相同的输出。 我是什么

3 个答案:

答案 0 :(得分:6)

使用virtualoverride可以完全替换Work方法,无论变量声明为何种类型。如果某个方法声明为virtual,则CLR会检查该对象是否为派生类,以及该方法是否已被覆盖。如果方法不是虚拟的,则CLR只从该对象被声明为的类型中调用名为Work的方法。

    static void Main(string[] args)
    {
        Employee emp = new Employee();
        Manager exec = new Manager();

        DoWork(emp); // employee works and gets pay check
        DoWork(exec); // if virtual and override are used, MANAGER get pay check
                      // however, if you don't override the method, DoWork
                      // will treat the argument as an Employee.
    }

    static void DoWork(Employee emp)
    {
        emp.Work();
        emp.GetPayCheck();
    }

答案 1 :(得分:2)

即使指针语法消失了,您使用C ++指针和引用变量学习的概念也存在。 virtual在C#中和在C ++中做同样的事情:它在一个子类中声明一个可替换的方法。 override替换方法是否为虚方法,这就是为什么你的代码以它的方式工作的原因。

答案 2 :(得分:1)

尝试:

Employee manager = new Manager();
manager.GetPayCheck();

你是否仍然得到相同的结果?

答案:你没有。

如果您使用virtualoverrideManager版本的GetPayCheck()无论如何都会被调用。如果您省略virtualoverrideEmployee版本的GetPayCheck()将被调用,如果您的实例被转换为Employee,{{1如果您的实例转换为Manager,则会调用版本。后一种情况称为“隐藏”,您将收到编译器警告,建议您使用Manager关键字明确隐藏是故意的。