Stuff that's in my head

Can open... Worms? everywhere! The blog of Colin Angus Mackay
posts - 379, comments - 486, trackbacks - 52

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.

Print | posted on Friday, October 10, 2008 10:28 PM

Feedback

Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

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
10/31/2008 9:32 AM | Johny Iversen
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

@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.
11/1/2008 8:06 AM | Colin Angus Mackay
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

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.
12/13/2008 5:49 PM | PIEBALDconsult
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

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?
12/31/2008 10:35 AM | Gonzalo Vazquez
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

@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.
12/31/2008 12:27 PM | Colin Angus Mackay
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

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.
12/31/2008 4:45 PM | Nick Hannum
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

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.
11/12/2009 4:36 PM | stoneskin
Gravatar

# re: Method hiding or overriding - or the difference between new and virtual

@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.
11/12/2009 7:18 PM | Colin Angus Mackay

# re: Method hiding or overriding - or the difference between new and virtual

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.
11/20/2009 10:05 AM |

Post Comment

Title  
Name  
Email
Url
Comment   

Powered by: