Would some OO guru mind explaining the significance of these two keywords--what they do and for which context is one or the other preferable?
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.
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.
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
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.
An Example of Shadowing: Lets assume that you want to use a function in a third party component but the function is protected. You can bypass this constraint with simple inheritance and exposing a shadowed function which basically calls its base function.
Public Class Base
Protected Sub Configure()
....
End Sub
End Class
Public Class Inherited Inherits Base
Public Shadows Sub Configure()
MyBase.Configure()
End Sub
End Class
This is a recent MSDN link: Differences between shadowing and overriding
Shadowing protects against a subsequent base-class modification that introduces a member you have already defined in your derived class. You normally use shadowing in the following cases:
** You anticipate that your base class might be modified to define an element using the same name as yours.*
** You want the freedom of changing the element type or calling sequence.*
(I'm yet to investigate usage with respect to scope and types)
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 proprty named Response to shadow the original in a base class. I couldn't use overrides, since this property is not overridable. Very convinient:)
I have a generic class, from which I inherit into 5 specific classes, and generic collection class which also inherits into 5 specific classes. Generic collection class has a serialization/deserialization methods. And here the problem starts. When serialization is called, the parent class metod is called and the specific class is treated as parent. This makes deserialization to fail as serializer expects matching class name.
I've declared serialization/deserialization methods in specific classes, but, although I use "Shadows" keyword, they are never called. I guess that because they are called from generic class, they are recognized as generic class' methods.
Please advise.