Rhaegar
Rhaegar

Reputation: 51

Virtual and override

I came from a world of C++ and as you may know there is only one keyword for virtual methods there, which is virtual. So in C++ you redefine virtual method in derived class using the same virtual keyword (in C# you use override). I'm perfectly aware of polymorphism and how do "override" and new works in C#. However, I wasn't able to find in books whether there is some idea behind creating two different keywords for virtual methods in base and derived classes, namely virtual and override corresponding? Or was it made just for clarity?

Upvotes: 4

Views: 7014

Answers (3)

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29213

In a 2003 interview, Anders Hejlsberg (the lead architect of C#) explained that the decision to have two distinct keywords was made mainly to address a versioning concern with base components changing across versions. In his own words (emphasis mine):

I can demonstrate to you a very real world versioning problem, one that indeed we see now from experience with Java. Whenever they ship a new version of the Java class libraries, breakage occurs. Whenever they introduce a new method in a base class, if someone in a derived class had a method of that same name, that method is now an override—except if it has a different return type, it no longer compiles. The problem is that Java, and also C++, does not capture the intent of the programmer with respect to virtual.

When you say "virtual," you can mean one of two things. If you did not inherit a method of the same signature, then this is a new virtual method. That's one meaning. Otherwise it is an override of an inherited method. That's the other meaning.

From a versioning perspective, it is important that the programmer indicate their intent when they declare a method virtual. In C#, for example, you must explicitly indicate which meaning of virtual you intend. To declare a new virtual method, you just mark it virtual. But to override an existing virtual method, you must say override.

As a result, C# doesn't have the particular versioning problem I described earlier in which we introduce a method in a base class that you already have in a derived class. In your class, you would have declared foo virtual. Now we introduce a new virtual foo. Well, that's fine. Now there are two virtual foos. There are two VTBL slots. The derived foo hides the base foo, but that's fine. The base foo wasn't even there when the derived foo was written, so it's not like there's anything wrong with hiding this new functionality. And things continue to work the way they're supposed to.

So, you're extending a class. You add a virtual method to your class. In a later version, the base class adds a virtual method of its own and its signature matches the signature of your virtual method. This could happen either by complete accident or because your methods happen to actually serve related purposes (and you simply addressed a particular need before the base class designers did). In any case, the situation is ambiguous.

Thanks to the existence of two distinct keywords (virtual and override), the C# compiler can give you non-breaking behavior (by hiding the inherited virtual method and keeping it separate from your virtual method) and also bring the issue to your attention, through this warning:

'Derived.Foo()' hides inherited member 'Base.Foo()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

It now asks you to address the issue by making your intention explicit: From now on, are you overriding the inherited method that has been added (override)? Or are you still starting your own virtual method that now hides the inherited one (virtual and new)?

Upvotes: 9

DrewJordan
DrewJordan

Reputation: 5314

This is a good question.

You use the override keyword to override a virtual method because you can actually define a second virtual method in a derived class, with the same signature as the base classes virtual method, and this can be overridden as well.

This is the actual example from MSDN:

using System;
class A
{
   public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
   public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
   new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
   public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
   static void Main() {
      D d = new D();
      A a = d;
      B b = d;
      C c = d;
      a.F();
      b.F();
      c.F();
      d.F();
   }
} 

yields:

B.F
B.F
D.F
D.F

because:

the C and D classes contain two virtual methods with the same signature: The one introduced by A and the one introduced by C. The method introduced by C hides the method inherited from A. Thus, the override declaration in D overrides the method introduced by C, and it is not possible for D to override the method introduced by A.

Upvotes: 7

Stefan Zvonar
Stefan Zvonar

Reputation: 4309

I am assuming for clarity. I personally prefer having override for when changing behaviour from a parent class. Also, I believe it provides more clarity in the fact that C# does not allow multiple inheritance, where as perceivably, a class in C++ could inherit from both a Grand Parent and Parent class.

Upvotes: 0

Related Questions