Not sure how coherent this is going to be. Just sorting out a few details of OO and sharing them w/ the interweb.
In OO programming we typically deal with class, instances of classes (objects) and interfaces. In .NET, and C# specifically, we have inheritance. A C# class can inherit from one parent; we don’t do multiple inheritance around here. However, a C# class can implement as many interfaces as needed.
C# has the concept of an abstract class. An abstract class cannot produce any instances. It has to be inherited. An abstract class can provide default implementations for its methods, an interface cannot.
If you want to mark that a method should be overridden in a child class you can mark the method with virtual. Private methods cannot be virtual (duh). You can also mark a method as abstract and provide no method body in the parent. If a child inherits the parent then it must provide an implementation of the abstract method. In your child class you use the override keyword to tell the compiler that you are supplying an implementation of the method.
If you don’t want anybody to be able to inherit from you class you mark it as sealed. Obviously an abstract class cannot also be sealed. You can also mark override methods as sealed. Doing so will prevent grandchildren from making further changes.
All of that is pretty basic stuff. Now for some fun stuff:
You have a third party library that provides a class X with method Y. Y is just a regular old method that you want to override. You create Xprime and in your class you use the new keyword to supply a new implementation of Y. In your code you create an instance of Xprime and pass it to a method expecting an instance of X where it calls Y. What happens? You also pass Xprime to a method expecting an Xprime and it calls Y. What happens?
Same as before but this time you forget to use new. What happens?
Overriding non-virtual methods is tricky. Virtual and non-virtual methods are treated differently by the compiler and the runtime. In C++ we have the concept of a v-table. Same in C# land. Essentially we build up a table of function pointers pointing to all of our virtual methods. When a child class overrides a method it replaces the pointer in the vtable. In the case of a non-virtual method there isn’t a pointer to replace. If we are talking to an instance of a specific class we get that specific class’s implementation of the method, it effectively hides the child’s new implementation unless you are talking to the child class. Keep in mind the difference between a class and an instance/object.
What about virtual methods? What if I forget the override keyword? How will that affect things?
Strange things happen. If you do not explicitly mark your methods as overrides the class type being acted on will determine what code gets executed. If you are passing a parent type around then the parent’s methods will be executed.
Is this useful or just a nice way to introduce bugs in to your code if you aren’t careful? I can imagine a few situations where leaving off the override or new could be mildly useful. However, I feel this is largely something that should be paid attention to.
I wrote a simple VS solution that tries out several of the permutations that I thought of here. If I had time I’d love to dig under the covers and see how things are being expressed in IL. But that will have to wait for a bit. I’ll get the code uploaded later.
This really isn’t a big deal. It’s trivia that comes up during interviews.