2011-10-31 78 views
1

我一直在用C++编程一段时间,现在我开始使用C#,但是我无法得到关于virtualoverride关键字的想法。既然指针和所有与它相关的东西大部分都是从C++中删除的,我们并不真的需要它们吗?或者我错过了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(); 
     } 
    } 
} 

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

+2

你实际上并没有做多态。 –

回答

6

使用virtualoverride可以完全替换Work方法,而不管变量声明为什么类型。如果一个方法被声明为虚拟的,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(); 
    } 
2

尽管指针语法不见了,但您用C++指针和引用变量学习的概念仍然存在。虚拟在C#中的功能与C++中的功能相同:它将一种方法声明为可在子类中进行替换的方法。覆盖会替换方法是否是虚拟的,所以这就是为什么你的代码按照它的方式工作。

1

尝试:

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

你仍然得到同样的结果,无论采用哪种方式?

答:你没有。

如果使用virtualoverride,则ManagerGetPayCheck()版本会被调用,无论如何。如果您省略了virtualoverride,则EmployeeGetPayCheck()版本将在您的实例被转换为Employee时得到调用,如果您的实例转换为Manager,则会调用Manager的版本。后一种情况称为“隐藏”,您将得到一个编译器警告,建议您使用new关键字来明确隐藏是有意的。