I have a question, what is the difference if you:
a) don't use the override, but use the virtual
b) use the virtual, but not the override
c) don't use either of the keywords
in the example you have given?
Good questions. I'm glad you're asking for clarification.
Before answering your questions, let me go back and try to summarize what's going on here again.
Keep in mind here, that what we're trying to do is allow derived classes, ones that represent more specialized types of things, handle specific tasks in ways that are different from the less specialized base class.
The abstract, virtual, and override keywords all play a different part in setting up this behavior.
In the Base Class
For starters, in the base class, you have three choices: prevent any derived class from doing it their own way, allowing derived classes to provide their own way, or requiring the derived class to do it their own way.
To prevent derived classes from providing their own implementation, you don't need to add any special keyword. That's the default behavior. So derived classes can't provide an alternate implementation to this method:
public void DoSomething() { Console.WriteLine("Hi"); }
To allow derived classes to make a change, you need to add in the virtual keyword. With the code below, derived classes will have the ability to have DoSomething do something besides print out "Hi". (We'll talk about how to do that in a second.)
public virtual void DoSomething() { Console.WriteLine("Hi"); }
To require the derived class to provide its own implementation, you use the abstract keyword. With this keyword, you can't provide an implementation of the method in the base class, and the derived class will need to implement its own version. This looks like this:
public abstract void DoSomething(); // Note there is no implementation of this method here.
I should also remind you that in this case, if you have any abstract methods, the base class itself can't actually be used. It contains some methods that it doesn't have an implementation for, which makes the base class unusable, by itself. Instead, the idea is that it provides most of the logic, and specific derived classes will finish up the missing pieces. These derived classes can be used. But you have to tell C# this explicitly. The class itself must also be marked with the abstract keyword:
public abstract class Base { public abstract DoSomething(); // You're allowed to have other, non-abstract methods, properties, // and instance variables in here if you want. }
In the Derived Class
With the base class set up properly, we can move on to the derived class.
If the base class allows or requires the derived class to provide an alternate implementation (the method is virtual or abstract) you can (or must) provide an implementation of that method in the derived class, and include the override keyword:
public class Derived : Base { public override void DoSomething() { Console.WriteLine("Bye"); } }
You use override regardless of whether the base class used virtual or abstract. It doesn't matter.
On the other hand, if you use override on a method that doesn't allow you to override it (not marked with virtual or abstract in the base class) you'll get a compiler error. In this case, the base class implicitly doesn't allow alternate implementations of the method in question, and you're trying to do exactly that with the override keyword in the derived class.
If you do nothing in the base class, and also do nothing in the derived class, but the method is exactly the same (as would be the case if you were trying to override it) you end up in a different place altogether. Because the base class didn't allow it, you can't provide a different implementation for it. However, you are technically allowed to provide a completely new, unrelated method that has nothing to do with the one in the base class but which still has the same name and parameters. This, however, is a very bad idea as you'll end up with two methods that look the same, and depending on how you use it, you'll end up calling one sometimes, and the other different times.
I'd guess 95% or more of the time that this shows up in code (identical method name and parameters in the derived and base classes) the intention was to override the method in the base class, but you're just missing something. Perhaps you need to make the method in the base class abstract or virtual. Perhaps you just need to add in the override keyword in the derived class. So the solution is to just fix it. If you don't fix it, then you get an extra method that looks all too similar to the one in the base class. This is an interesting scenario because what happens is probably not what people were intending to happen 95% of the time.
Fortunately, to address this, the C# compiler will give you a warning telling you that it's doing this, and try to get you to either fix it (add in the override keyword, and also fix the base class if needed) or to add in the new keyword on the method, which tells the compiler, "Yes, I'm in that 5% area, where this is what I really want to do." It doesn't change the actual behavior (of creating two practically indistinguishable methods) but it does get rid of the compiler warning.
To Answer Your Questions…
A: If you use virtual in the base class and don't use override in the derived class, you'll end up in that weird area that I was describing, creating two nearly identical methods. You don't want that. Add the override keyword.
B: (Wait… on reading this again, it says the same thing as A, but in reverse… I'll assume you meant the opposite?) If you don't use virtual in the base class (or abstract), but use override in the derived class, the compiler will generate an error, because you're trying to override a method that doesn't allow you to override it with an alternate implementation.
C: If you don't use either, then the base class implicitly doesn't allow you to override the method, but because the methods match, you'll get that warning saying, essentially, "fix this to do overriding correctly (what you most likely want) or stick on the new keyword if you really wanted to create two identical methods and get rid of this warning."
I kind of feel like I nearly rewrote this entire tutorial in different words… but that's OK if it helps!
Let me know if you're still confused about any of this, and I'll see what I can do.
Sorry for posting such a long answer!