D'Arcy from Winnipeg
Musings of a Canadian BizTalk and SOA Developer

Overloads and Shadows (VB.NET)

Tuesday, January 15, 2008 3:07 PM

I'm teaching an 'OO with VB.NET' course right now, and last night was the talk about overloading, overriding, and shadowing...specifically around inheritance. Prepping for this showed some interesting behavior that I wasn't aware of, and wanted to share.

Overloading a function or sub means that you have a method with the same name as an existing method. If these are in the same files, then you need to specify different signatures for them. However, you could have a situation where a base class and a derived class both have the same method signatures and method names. In this case, you *don't* have to have different signatures: the compiler is fine with letting you have a derived class with the EXACT method signature as one in your base class.

This is an issue though, because what you're really doing is Shadowing. Where Overriding requires the base class to identify a method as overridable and the derived class to specify that its class is overriding, Shadowing has no such rules. Shadowing clobbers your base class method in favor of the derived class method...and worse yet, this is the default behavior of VB.NET.

So it would appear that Overloading in a derived class and Shadowing are the same thing. Let's say we have two classes:

Class A
Class B

Class B inherits from Class A. Both have a method called DoSomething( ) in them, and class B overloads that method.

If you created an instance of Class B...

Dim _classB as ClassB
_classB = new ClassB

...and you called DoSomething( ), the method in Class B would execute. If you *didn't* overload that method the same thing would happen. Why? Because the default behavior is to shadow the method.

However...the rules for shadowing change when you're dealing with a variable declared as the base class, but instantiated to a derived class:

Dim _classB as ClassA
_classB = new ClassB

If I were to call the DoSomething( ) method from _classB, it would actually fire off Class A's version of the method, regardless if I overloaded or shadowed the methods in Class B.

So how do you avoid this mess in your code? By being prudent in how you write your methods:
- If you overload a method in a derived class, ensure that it has a different signature than the base class method.
- If you need to overload the method in a derived class with the identical signature from the base class's method, then use the Overridable and Overrides keywords to ensure that the method is picked up properly. This way, even in the second class example, your method from _classB will fire as expected
- Favor composition over inheritance. This is a tried and true phrase: even though you *could* solve a problem by inheriting, see if there's another option that doesn't require you to inherit and compose your object of other helper objects instead.

D

 


Feedback

# re: Overloads and Shadows (VB.NET)

Although, if we're being fair, you are warned:

Warning 1 sub 'DoSomething' shadows an overloadable member declared in the base class 'ClassA'. If you want to overload the base method, this method must be declared 'Overloads'.

So once you are aware of the difference, you can make an informed decision as to what you need to do.

It would be worse if it just blindly acted different without any sort of warning, obviously that could potentially cause debugging headaches. 1/16/2008 7:49 AM | Carl

# re: Overloads and Shadows (VB.NET)

For shadows yes.

It would be nice to see a similar warning come up for when you overload a function in a derived class that has an exact signature as the one in the base. Nothing displays to warn the dev that the derived class's method will be used only when a variabled of that derived class is declared and not of the base type (which like you said though: once you're aware of hte difference, you'd know to avoid)

D 1/16/2008 8:21 AM | D'Arcy from Winnipeg

# re: Overloads and Shadows (VB.NET)

Thanks for this. I've been reading up on vb.net and both books I've been reading show examples of using "Overloads" on a method of a derived class that has the same signature as the method of the base class.

I got to your blog by googling for this, as I'm trying to understand why you would want your code to exhibit this behavior.

I think your final comment about either ensuring both methods have a different signature. Or use "Overrides" instead of "Overloads" is a much better practice then using "Overloads" with the same signature.

It would make sense to me that having the same signature could lead to debugging nightmares. 3/18/2008 5:24 PM | perry

Post a comment





 

Please add 6 and 6 and type the answer here: