Method hiding or overriding – or the difference between new and virtual

When developing applications it is very important to understand the difference between method hiding and method overriding.

By default C# methods are non-virtual. If you are a Java developer this may come as a surprise. This means that in C# if you want a method to be extensible you must explicitly declare it as virtual if you want to override it.

So, what is overriding? Wikipedia has a succinct definition. Method overriding is a language feature that allows a subclass [aka derived class] to provide a specific implementation of a method that is already provided by … its [superclass] [aka base class]. The implementation in the subclass overrides (replaces) the implementation in the superclass.

The important thing to remember about overriding is that the method that is doing the overriding is related to the method in the base class.

Method hiding, by contrast, does not have a relationship between the methods in the base class and derived class. The method in the derived class hides the method in the base class.

I wouldn’t personally recommend method hiding as a strategy for developing code. In my opinion, if you feel the need to hide the method on the base class then you are most likely doing something wrong. I haven’t come across any scenarios where method hiding couldn’t be better implemented by other means, even as simple as just naming the method on the derived class to something else.

Let’s look at some code to show you what I mean. First off we are going to use this class structure (it’s my favourite when showing off inheritance, and you may have seen variations of it already on my blog).

Partial Class Diagram

Let’s say that the Dog class has a method call Bark()

public class Dog: Mammal
{
    public void Bark()
    {
        Console.WriteLine("Woof!");
    }
}

So far, so good. We can call it like this:

static void Main(string[] args)
{
    Dog d = new Dog();
    d.Bark();
    Console.ReadLine();
}

And the output of the program is as you’d expect. “Woof!” is written to the console.

Now, Chihuahuas are nippy wee things and they tend to “yip” rather than “woof” so what we’ll do is create a Bark() method in Chihuahua class that writes out “Yip!” instead.

public class Chihuahua : Dog
{
    public void Bark()
    {
        Console.WriteLine("Yip!");
    }
}

What happens here is that the C# compiler will display a warning to indicate that it has found a situation that it can guess at the intended functionality, but it really wants to to be explicit.

warning-message

‘Animals.Chihuahua.Bark()’ hides inherited member ‘Animals.Dog.Bark()’. Use the new keyword if hiding was intended.

By inserting the new keyword between the public and the void in the method declaration we can get rid of this warning. We are being explict and telling the compiler that we know what we are doing. So, what are the implications of method hiding? Consider the following bit of code:

static void Main(string[] args)
{
    Dog d = new Chihuahua();
    d.Bark();
    Console.ReadLine();
}

Well, if you have a Dog reference that actually refers to an instance of the Chihuahua class then when you call bark it will still say “Woof!” That goes against many people’s expectations. This is because you’ve actually drawn that line in the sand and are saying that the Bark method on Chihuahua is unrelated. If you hold a reference to a Dog then you may not be expected to know about the existence of a Chihuahua so if your calling code suddenly got the functionality of the Bark method in the Chihuahua class then it might break. The CLR cannot make that decision for you. If you do know about your Dog reference actually being a Chihuahua then you must cast it before using it. However, that means you are likely to have to litter your code with conditional statements based on the actual type of the object and that defeats the power of having an object oriented language.

What you should have done is make the Bark method virtual then overriden the derived version like this:

public class Dog : Mammal
{
    public virtual void Bark()
    {
        Console.WriteLine("Woof!");
    }
}
public class Chihuahua : Dog
{
    public override void Bark()
    {
        Console.WriteLine("Yip!");
    }
}

This way when you have a Chihuahua object then the correct Bark method is called regardless of the type of the reference so long as the reference type can see a Bark method on that hierarchy

The way I see it is that there is no reason to have to draw that line in the sand and use the new keyword in the context of method hiding. If you feel the need to do that then your two realistic options are either to consider whether what you really want to do is make the base virtual and then override in the derived class, or whether you need to think of a better name for the method in the derived class. If the methods are related (like the Bark example above) then method overriding is what you need. If they are not related then make that explicit by giving the method in the derived class a different name.

17 Comments

  1. Hi Colin,Thank you for a very good introduction to these two terms. However, I think I can come up with a situation where hiding might not be so bad after all.I’m thinking of singleton generic collection classes. There’s only 1 collection for each type in such a setup, and if you e.g. inherit from the List<> class, then you’ll have to use hiding, if you want to provide new functionality to e.g. the Add() method. How would you work around that without the use of hiding, and should you even do so? I mean, would not hiding be the best choice at such a scenario?Best regards,Johny Iversen

  2. @Johny Iversen: I wouldn’t do that. If I decide I want to add new functionality I need to be able to override the method. Hiding it won’t give me what I want. As I mentioned above, if I have a reference to the base class and I call Add I’ll get the functionality of the base class, not the functionality of the method of the actual class that the object is. So I am not getting the proper OO functionality that I’d expect.

  3. I agree, this week I was trying to make a derived Queue<T>, but although Microsoft didn’t seal the class, they also didn’t make the members virtual.Eventually I just wrapped the Queue<T> and called it good.I don’t know Java, but I agree with having members virtual by default. Any perceived “performance hit” due to vtables is outweighed by ease of derivation.As far as I’m concerned, if the members aren’t virtual, the class is as good as sealed, don’t derive from it.

  4. Hi Colin.I mostly agree with you but there is one point I disagree with.Say that you have a class that needs to implement static methods, as far as I know it is impossible to create virtual static classes in c#, as far as I know it sucks, but it is as it is so even if the methods are related I need to use hiding even though is unelegant, am I wrong?

  5. @Gonzalo Vazquez: If you have static classes you cannot use inheritance at all so your point is moot since you can never be in the situation where you could possibly benefit from method overriding or method hiding.If, however, you have static methods on a normal class then the compiler will warn about method hiding if you don’t use the “new” keyword. But, what real benefits of inheritance are you actually getting? If you need to call a static method from outside the class in which it is defined you have to use [class-name].[method-name]. If you are within the class you can drop the [class-name] part and get the version that you would have got by writing [current-class-name].[method-name]. So, the limited benefits are confined only to the class structure you are in. You get no benefit externally because you have to know the classname in the first place, which you would need to know if you are calling a regular method if you are using “new” to hide its base, lest you get the base implementation.If you have virtual methods you don’t need to know the class name of the method you are calling. The reference can be to a known base class even if the actual object it refers to is an unknown derived class. With method hiding (static or otherwise) you are forced to know the actual class of the method lest you call the wrong one, thus losing the real benefit of virtual methods.So, I think that my point stands. If you are going to use “new” to hide methods you are going to confuse people as it will introduce subtle bugs. It doesn’t matter that in some situations it is the only way to make it look like it is using virtual methods, you are still not getting the full benefits of virtual methods, it is just an illusion. And if you have that façade you should go the full way and not use a half way house like method hiding, because people won’t instantly see the differences and assume you’re using the full thing.

  6. Nick Hannum says:

    Do you also find it misleading when an overridden method does not fall through to the base class functionality? I think many people assume that if it is derived implementation instead of method hiding, it will sit on top of the base functionality and fall through with a base.[method-name] call. I know that this can be pretty specific to the method itself, but it seems that it’s the natural assumption, especially since Visual Studio puts the the base call in automatically when you have it create the override for you.I agree though; I can’t find a decent case of wanting to use the same name for something that shouldn’t use inheritance.

  7. stoneskin says:

    As a Java programmer just getting started on c# I found this very useful.On the whole I just don’t understand the point or need to ever hide a method. Thanks for the article.

  8. @stoneskin: If it is any consolation to you, I don’t get it either. It seems to be a pointless feature and it causes more grief than relief as developers who don’t understand it get it magnificently wrong and cause untold havoc in the system as a result.

  9. I had a query why we need to overide a method when we can create a new method explicitly and achive the same fucntionality but the last few lines of this article really solved my query stating when the functionality is realted you can use the same method name and type i.e the signature and overide (replace ) the base class implementation.

  10. Jae Kim says:

    Thank You Colin! I am learning C# and got stuck on Hiding methods. I kept re-reading the section but kept failing to understand the point of using Hiding. And it bothered me to continue on without understanding something to a “decent” degree. So I kept reading, studying, finally, I began to Google the subject and upon reading this post, it’s a slam dunk closure. Wish I could get back the nearly 45 minutes I spent trying to figure out the point of Hiding … or wish that my textbook simply briefed your point. Thanks again.

  11. now I really come to know what’s the difference b/w hiding and overriding.

  12. Mark Bennion says:

    Thank you so much !!! I have one page in a fairly big project that had to override the MenuButton_Click method. I have this method defined in a common class and all pages are derived from this class. The “new” keyword did get rid of the compiler warning, but the method was not overriden. I changed it to a virtual method and followed your instructions. It works perfectly! Thank you !!!

  13. Charles Roland says:

    Hi Colin,
    I read a couple other websites before this one, and they did not explain things very well. I learned OO on Java and so I was struggling with the question “why does the base version of the function run?”. Your example with the commands was so clear that I got it right away:
    Dog d = new Chihuahua();
    d.Bark();

    Just naming the variable “d” was enough to get the gears turning. Thanks much!

  14. TetheredSun says:

    ‘In my opinion, if you feel the need to hide the method on the base class then you are most likely doing something wrong. I haven’t come across any scenarios where method hiding couldn’t be better implemented by other means, even as simple as just naming the method on the derived class to something else.’

    First, thank you kindly for your post. I came upon it as I am having doubts if using the ‘new’ keyword is advisable or bad practice, but the alternatives seem unsavoury. Let me summarise my problem in brief. Please bear with me as I am just a self-taught amateur.

    I should like to implement a class AccumulatorList that extends List with an Accumulator field that calculates the statistics (mean, standard deviation, standard error) of the items as they are added (ie, without enumerating a list, simply by modifying single values such as sum, count and squared sum). Whenever I add a new value to the list, I also have to register it in the Accumulator. The most natural solution would be to override the Add(T item) method. Alas, it is not virtual. Defining a new method with a different name will not do as I do not want the List.Add(T item) to be called without the item being registered in the Accumulator. I could implement IList anew (basically by copying code from List using the reflector and changing what’s necessary), but it seems too much work for such a simple modification and I have even stronger doubts about its advisability (copying code instead of using inheritance) than about that of the ‘new’ keyword.

    Is it a valid use of the ‘new’ keyword or am I going astray somewhere (apart from the fact that whenever I modify the list, my Accumulator loses its advantage as I have to recalculate the statistics)?

    Thank you for your thoughts in advance.

    1. So, I’d say that implementing your accumulator class as an IList<T> isn’t so bad. I wouldn’t use reflector to copy the functionality of a List<T>, I’d use composition instead. Basically, my AccumulatorList<T> class would have a List<T> as a private field, and all the method implementations defer to the field, calling its implementation instead of rewriting it. Your class may look something like this:

      public class AccumulatorList : IList<T> where T : IConvertible
      {
        private List _list = new List();
      
        public IEnumerator GetEnumerator()
        {
          return _list.GetEnumerator();
        }
      
        IEnumerator IEnumerable.GetEnumerator()
        {
          return _list.GetEnumerator();
        }
      
        public void Add(T item)
        {
          _list.Add(item);
          // TODO: List modified - Do stuff to deal with this.
        }
      
        public void Clear()
        {
          _list.Clear();
          // TODO: List modified - Do stuff to deal with this.
        }
      
        public bool Contains(T item)
        {
          return _list.Contains(item);
        }
      
        public void CopyTo(T[] array, int arrayIndex)
        {
          _list.CopyTo(array, arrayIndex);
        }
      
        public bool Remove(T item)
        {
          bool result = _list.Remove(item);
          // TODO: List modified - Do stuff to deal with this.
          return result;
        }
      
        public int Count
        {
          get { return _list.Count; }
        }
      
        public bool IsReadOnly
        {
          get { return ((IList)_list).IsReadOnly; }
        }
      
        public int IndexOf(T item)
        {
          return _list.IndexOf(item);
        }
      
        public void Insert(int index, T item)
        {
          _list.Insert(index, item);
          // TODO: List modified - Do stuff to deal with this.
        }
      
        public void RemoveAt(int index)
        {
          _list.RemoveAt(index);
          // TODO: List modified - Do stuff to deal with this.
        }
      
        public T this[int index]
        {
          get { return _list[index]; }
          set 
          { 
            _list[index] = value;
            // TODO: List modified - Do stuff to deal with this.
          }
        }
      }
      

      So, the above class is incomplete, as you have to put in your implementation for calculating sums, etc.

      So, the reason I put in a constraint on T is that whatever value you place into the list you need a standard way of performing your calculation as you cannot guarantee that T implements the + operator, for example. If T implements IConvertable you can have your calculation engine convert to, say, double, which you know does implement the + operator then perform the calculation and finally convert back as needed.

      1. TetheredSun says:

        Thank you very much, sir. I much appreciate your advice.

        ‘So, the reason I put in a constraint on T is that whatever value you place into the list you need a standard way of performing your calculation as you cannot guarantee that T implements the + operator, for example. If T implements IConvertable you can have your calculation engine convert to, say, double, which you know does implement the + operator then perform the calculation and finally convert back as needed.’

        In fact, I came across a very good solution to this at SourceForge. It requires some work but I never cease to relish its elegance:

        http://www.codeproject.com/Articles/33617/Arithmetic-in-Generic-Classes-in-C

        In building my Accumulator (T), I used Bill Fugina’s great idea as modified by PIEBALDconsult (see the comments to Bill’s article). Though it is still not guaranteed that there will be a calculator (called OperationProvider in PIEBALDconsult’s code) for my generic type T: if no such calculator exists, I shall get an InvalidOperationException.

        Thank you very much again and have a nice weekend.

        Péter

        1. TetheredSun says:

          Oh, and I have found the pattern put forward in the article very productive: I could apply the same to construct a generic framework for the binary serialisation of lists of numeric types (short, int, long, float, double, Complex) and the string conversion and parsing of the very same types.

Leave a Reply to Mark Bennion Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s