Object-Oriented Programming in C# .NET - Part 5

A discussion of virtual and override members, overriding operators, interfaces and nested types in C#

Introduction

In the last part of Object-Oriented Programming, we will go through the following:

Virtual and Override Members

Overriding Operators

Interfaces

Nested Types

What are Virtual and Override Members?

Virtual and Override members (methods, properties) are another kind of polymorphism. When you derive from a base class, that base class may have some virtual members and allow you to override them. That is, change their implementation so that when called by an object of your class does a different thing. The best way of understanding it is through an example. Suppose you derive from a base class named Car. This Car class possesses a method named Accelerate:

When you instantiate an object of type car and call the Accelerate method, the value stored in speed will increase by 10. Now, you want to create a much faster Car class that when its Accelerate method is called, its speed increases by 30. And, of course, this new car derives from the base car class:

If you build the solution, you will get a warning. The solution to this warning is that the Accelerate method in Car class should be declared as virtual which allows you to override it within the MuchFasterClass:

So, as you see, the + operator does different things based on the type it’s working on. What if you want to make the + operator do yet another different thing on objects of your class. Suppose you have a Point class which has an X and Y coordinates. You want to override the + sign on this Point class so that when it’s applied to objects of type Point, it simply adds the Xs and Ys and return a new Point object:

Note the signature of the method that overrides the + operator. It’s declared as public and static (always must be), it returns an object of type Point, it has the operator keyword, it specifies the name of the operator that is overriding. Now, look at the following code:

Run the solution and see the results. You can override the *,/,- operators similarly.

What are Interfaces?

Interfaces are like contracts. If your class is to have a certain capability, it must override a certain interface. Another use of interfaces is providing multiple inheritance, which is impossible in C# using class derivation. That means that you can derive from only and only one class but you can implement as many interfaces as you desire. Suppose you want to make an Animal hierarchy. You create a base abstract class named Animal that every class in the hierarchy derives from. The reason to create the Animal class as abstract is that it should not be instantiated (an abstract class cannot be instantiated.). Now some animals are carnivore, some are herbivore, some are reptiles. You cannot make a class, say, Crocodile derive from Animal, Carnivore, Reptile. Instead, you declare everything except the base Animal class as interfaces. Therefore, the Crocodile class is an Animal which implements the Carnivore, Reptile interfaces (which are also like contracts. If the Crocodile is to be thought as a carnivore and a reptile, it must implement a certain, in this case Carnivore and Reptile, interfaces.). I won’t write the codes for all of these classes, but I assure you will get the idea:

There are lots of built-in interfaces which you can use to give your class additional functionality. For instance, if you want your class to be sortable (if you have an array containing objects of your class and you want to sort that array), you must add IComparable interface to your class and implement its CompareTo method.

One interesting thing about interfaces is that you can assign an object of a particular type to an interface provided that class implements that interface as you can do the same with an abstract class:

What are Nested Types?

You can declare a class within another class. The inner class in called the nested class and the outer class is called the nesting class. This is done when the nested class is meaningless out of the scope of the nesting class. In UML, this is called composition relationship. Suppose we want to declare a class named Human. Humans have hearts. Now, Heart is the other class we want to create. However, let’s assume that a heart is meaningless if there is no human. Therefore, we create the Heart class within our Human class:

The problem will only happen when you cast both as car, even when the second one is a fastCar. With the new you will never call the FastCar accelerate, while with the virtual/override you will.
I think that's the most important thing. And, an example using a List will be better to explain why you could have a FastCar typed as a Car, as beginners will simple say:
So, type it correctly, and there is no need to virtual.

Using the new keyword while declaring the function with the same name in derived class as function in the base class, the base class function will be ommited and warning message will not be displayed during compilation.

Indeed, I feel like the articles are more a list of all the things that are possible than an explanation on when to use what. If a beginner reads that, he might be tempted to use "new" all the time because it's faster than writing "virtual" and then "override"...

What's the difference between field and property? What is the goal of a finalizer (or what should you do in a finalizer)? What about the IDisposable interface? What is the point of polymorphism? (for me it's not really the fact that a method has several signatures, it's more that you can use an object without knowing its exact implementation). When should you override operators instead of creating methods? (eg should you be able to add cars?)

So basically, instead of saying "you can do this, you can do that", I feel you should say "you should do this in this case, that in that case". No need to explain everything thouroughly as it's a beginner article, but you can give links to good resources if someone wants to know more about a concept.