CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Grant Killian's Blog

No, this has nothing to do with beer -- but maybe it should?

Digesting Shadows vs. Overrides

As the class I'm teaching moves into OO topics, inevitably the subject of “Shadows” and “Overrides” comes up.  “Shadows” probably wins the award as the oddest sounding  addition to the VB language courtesy of .Net . . . although there is some strong competition from AndAlso and OrElse.  If you want more on this topic, check out this good MSDN piece on Shadows.

When you’re implementing behaviour in a VB.Net class that’s derived from a base class, you have two options: Shadowing or Overriding. 

To use Overrides in the derived class, the base class member you’re changing (or replacing) must be declared as Overridable.  This means that if the base class designer doesn’t have the foresight to flag the member as Overridable you can’t use Overrides in the derived class.  I suppose an organization could require every method to include the Overridable modifier before you compile and deploy the code, but that doesn’t seem like a good idea to me for security and other reasons.  My point is, it’s impossible for the base class developer to anticipate future needs to adjust an object’s behaviour in a derived class.

Enter the “Shadows” keyword.

The Shadows modifier comes into play when the base class HASN’T been flagged as Overridable.  You can replace any base class method with the Shadows modifier – but recognize that Shadows completely replaces the base class method without regard to method signature.

If this was all there was to it, this blog wouldn’t be necessary.  The issue grows more complicated because you can use Shadows when a method is marked as Overridable, begging the question: what impact does Shadows and Overrides have on my object’s behaviour?

The short answer: when working with an object polymorphically, Shadows promotes the variable over the type, while Overrides promotes the type over the variable.

Yikes, how’s that for a short answer?  An example will shed more light on this; consider the following class structure.
Public Class IcedTea
 Inherits Drink
 Public Shadows Function Consume() as String
  return "Consuming iced tea"
 End Function
End Class

Public Class Drink
 Public Function Consume() as String
  return "Consuming a Drink"
 End Function
End Class

Public Class AlphaRomeo
 inherits Car
 Public Overrides Function Drive() as string
  Return "Driving an Alpha Romeo"
 End Function

End Class

Public Class Car
 Public Overridable Function Drive() as String
  Return "Driving a Car" 
 End Function
End Class

These are two contrived examples of base and derived classes; the Car:AlphaRomeo example uses Overrides; the Drink:IcedTea example uses Shadows in the derived class and nothing special in the base class.  Let’s use this test harness to see these classes at work:
  dim objCar as New Car()
  ListBox1.Items.Add( objCar.Drive() )
  dim objAlpha as New AlphaRomeo()
  ListBox1.Items.Add( objAlpha.Drive() )
  objCar = objAlpha
  ListBox1.Items.Add( objCar.Drive() )

  Listbox1.Items.Add( "---------------------------" )

  dim objDrink as New Drink()
  ListBox1.Items.Add( objDrink.Consume() )
  dim objTea as New IcedTea()
  ListBox1.Items.Add( objTea.Consume() )
  objDrink = objTea
  ListBox1.Items.Add( objDrink.Consume() )

If you place this code in a button click event and run it, you’ll notice the Car:AlphRomeo example shows the “Type over Variable” behaviour.  Even though the variable is defined as a Car type, when it contains an AlphaRomeo type it uses the AlphaRomeo method.  The opposite is the case with the Drink:IcedTea example, it shows “Variable over Type” behaviour.  When the objDrink variable contains an IcedTea instance, the variable’s method takes precendence over the type.  This is just the opposite of the Overrides modifier and clarifies the short answer: when working with an object polymorphically, Shadows promotes the variable over the type, while Overrides promotes the type over the variable.

I think the Overrides behaviour is generally more desirable for object models and polymorphic processing (if I call drive on all the objects in a Car collection, I tend to want the AlphaRomeos to process their Drive() method and the regular Cars to process their Drive() method).  There are cases, however, where the Shadows modifier might be appropriate; if a method isn’t flagged as Overridable, of course, you don’t have any choice and have to go with Shadows.  Make an informed decision and know that Shadows promotes the variable over the type.

Sorry for this but I can’t help it . . . another lesson we can draw from this is that if you’re driving a car and drinking, make sure it’s only iced tea!

Happy .Netting.



Comments

grant said:

Here is the output displayed in the listbox:

Driving a Car
Driving an Alpha Romeo
Driving an Alpha Romeo
-----------------------------
Consuming a Drink
Consuming iced tea
Consuming a Drink
# August 25, 2003 5:33 AM

Karine Bosch said:

Thanks for your post. Just had a discussion on overrides and shadows. Had to search the web for a clear explanation of both. Couldn't explain it as good as you did.

PS. For me the thing in VB.NET that wins the award of oddest invention is the array and the fact that you get an extra element for free.
# April 13, 2004 10:00 PM

Abel said:

I got to this article while wondering about the effect of Shadows keyword on a class.? any comment on that?
# November 11, 2004 11:57 AM

Suman Kalyan said:

It is really good for understanding.
Thanks
# January 7, 2005 10:14 PM

jaytaylor said:

Great. Very clear.
# January 13, 2005 7:20 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!