'Shadows' vs. 'Overrides' in VB.NET

Viewed 69413

What is the significance of the two keywords Shadows and Overrides? What they do and for which context is one or the other preferable?

17 Answers

Overrides is the more normal qualifier. If the child class redefines a base class function in this way, then regardless of how a child object is referenced (using either a base class or a child class reference) it is the child function that is called.

On the other hand, if the child class function Shadows the base class function, then a child object accessed via a base class reference will use that base class function, despite being a child object.
The child function definition is only used if the child object is accessed using a matching child reference.

Overrides - Extending or creating alternate functionality for a method.

Example: Add or extended the functionality of the Paint event of a window.


    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e) ' retain the base class functionality
        'add code for extended functionality here
    End Sub

Shadows - Redefines an inherited method and forces its use for all classes instanced with that type. In other words the method is not overloaded but redefined and the base class methods are not available, thus forcing the use of the function declared in the class. Shadows preserves or retains the definition of the method such that it is not destroyed if the base class methods are modified.

Example: Force all "B" classes to use it's oddball Add definition such that if A class Add methods are modified it won't affect B's add. (Hides all base class "Add" methods. Won't be able to call A.Add(x, y, z) from an instance of B.)


    Public Class A
        Public Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
            Return x + y
        End Function
        Public Function Add(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Integer
            Return x + y + z
        End Function
    End Class
    Public Class B
        Inherits A
        Public Shadows Function Add(ByVal x As Integer, ByVal y As Integer) As Integer
            Return x - y
        End Function
    End Class

The "shadows" keyword essentially says "If whoever is accessing this object knows it to be of this type or one of its descendents, use this member; otherwise use the base one." The simplest example of this might be a base class ThingFactory, which includes a "MakeNew" method which returns a Thing, and a class CarFactory, derived from ThingFactory, whose "MakeNew" method always returns a Thing that will be of derived type Car. If a routine knows that a ThingFactory it holds happens to, more particularly, be a CarFactory, then it will use a shadowed CarFactory.MakeNew (if one exists), which can specify the return type as Car. If a routine doesn't know that its ThingFactory is actually a CarFactory, it will use a non-shadowed MakeNew (which should call an internal protected overridable MakeDerivedThing method).

Incidentally, another good use of shadows is to prevent derived classes from accessing Protected methods which will no longer work. There's no way of simply hiding a member from derived classes other than assigning a new one, but one can prevent derived classes from doing anything with a protected member by declaring a new protected empty class with that name. For example, if calling MemberwiseClone on an object would break it, one can declare:

  Protected Shadows Class MemberwiseClone
  End Class
Note that this does not violate OOP principles like the Liskov Substitution Principle, since that only applies in cases where a derived class might be used in place of a base-class object. If Foo and Bar inherits from Boz, a method which accepts a Boz parameter may legitimately be passed in a Foo or Bar instead. On the other hand, an object of type Foo will know that its base-class object is of type Boz. It will never be anything else (e.g. it's guaranteed not to be a Bar).

I agree with Jim. I've never found a legitimate use for Shadows, either. Usually if I see it, I assume that sub-section of the code needs to be refactored a bit.

I suppose it is there so that you can shadow a method from an assembly in which you do not have control over the source code. In that case, refactoring the parent class would be impossible.

I wanted to use System.Web.HttpContext.Current.Response instead of Response.redirect, and needed the convenience to code as Response.redirect. I defined a readonly property named Response to shadow the original in a base class. I couldn't use overrides, since this property is not overridable. Very convenient:)

I wouldn't consider Shadows to really be an OOP concept. Overrides indicates that you are providing new or additional functionality for a method/property etc that was declared in an ancestor class. Shadows really tricks the compiler into thinking that the parent method/property etc does not even exist.

I have no use for Shadows. Stick to Overrides. These types of helpful little "features" that VB has provided for years always end up causing you grief at some point.

Related