F
flat_ross
For anyone who is just getting into VB.NET and/or is starting to work
with inheritance I would like to point out a potential pitfall. We
found this confusion recently when code-reviewing an application. If
you have not used the keyword 'Overridable' then read on for sure...
If you setup a child class and you want to override a method in your
base class, you may see the squiggles under your child's method name.
The pop-up/build error says something like:
C:\Projects\TestShadows\Ball.vb(28): function 'GetMessage' conflicts
with function 'GetMessage' in the base class 'BaseClass' and so should
be declared 'Shadows'.
To fix this, you may go ahead and put the 'Shadows' keyword into your
function declaration and, voila, it works. You run your project and
the overriden (so you think) method fires perfectly.
Unfortunately, this 'Shadows' keyword does not truly provide
inheritance (in my opinion). If you decide to get into polymorphism
then you'll quickly see the problem. If you have an instance of your
child class stored in a datatype defined as your base class and then
call the 'Shadowed' method, then the instance will actually call the
base class' method and not your 'Shadowed' method. I would hazard a
guess that if you are just starting out then this is not the
functionality you would expect. I would assume that you'd expect the
'Shadowed' method. I am not sure what other code situations would
highlight this discrepancy; maybe this is the only one so if you never
plan to do it then you'll never have a problem. But I've learned never
say never...
To fix this, the proper way to setup methods for inheritance is to
setup the base class' method with the keyword 'Overridable' and then
setup the child's method as 'Overrides'.
An explanation of 'Shadowing' is in the VS2003 help:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2004APR.1033/vbcn7/html/vbconShadowing.htm.
If you can't find this file then click on F1 while your cursor is over
the Shadow keyword. Once help is up, scroll down and click the
'Shadowing' link under See Also. Even though it gives an in-depth
discussion on the concept it reads like it was written by a lawyer.
Only until I wrote up some demo code was I able to see the
ramifications.
I guess there are situations where Shadows may be of use but I think
it just confuses the situation (although again, never say never). The
only example I can think of is if you were upgrading the base class
and wanted to protect the child class' interface. But then you'd
probably have a good idea of what implications Shadowing has and your
object-oriented design would key in on that. Although I'm no OO
expert, I have no idea where Shadowing fits into the design anyway. I
would think designing Interfaces would come into play way long before
Shadowing.
Bottom line is I just wanted to point out that you may be incorrectly
using Shadows where you should be using Overridable/Overrides. I think
the compiler should have been designed to suggest using
Overridable/Overrides before ever suggesting Shadows.
Following is a code sample I used to demo the issue:
1) Create a web or win project, my example is a web project.
2) Add a class file to the project.
3) Make sure the new class file is empty and paste this content:
Public Class BaseClass
Public Overridable Function GetMessage() As String
Return "In BaseClass."
End Function
End Class
Public Class ShadowsMethod
Inherits BaseClass
Public Shadows Function GetMessage() As String
Return "In ShadowingMethodClass."
End Function
End Class
Public Class OverridesMethod
Inherits BaseClass
Public Overrides Function GetMessage() As String
Return "In OverridesMethod."
End Function
End Class
4) This code is for the page_load of a web form. If you want to use a
winform, you'll have to modify the Response.Writes to methods that
write to something on a winform (textbox, listbox, label, etc.)
Dim oInherits As New OverridesMethod
Dim oShadows As New ShadowsMethod
Dim oBase As BaseClass
'Call child's GetMessage
Response.Write(oShadows.GetMessage)
'Assign Child instance to a base datatype
oBase = oShadows
Response.Write("<br>Call method on derived class stored in
BaseClass datatype: ")
Response.Write(oBase.GetMessage & "<i><-- Because of
shadowing, the derived class' method is not called when it is assigned
to a BaseClass variable. Instead the base class' method is
called.</i>")
Response.Write("<br>--------------<br>")
'Call child's GetMessage
Response.Write(oInherits.GetMessage)
'Assign Child instance to a base datatype
oBase = oInherits
Response.Write("<br>Call method on derived class stored in
BaseClass datatype, ")
Response.Write(oBase.GetMessage & "<i><-- Because of
overriding, the derived class' method is called even when it is
assigned to a BaseClass variable.</i>")
Response.Write("<br>")
with inheritance I would like to point out a potential pitfall. We
found this confusion recently when code-reviewing an application. If
you have not used the keyword 'Overridable' then read on for sure...
If you setup a child class and you want to override a method in your
base class, you may see the squiggles under your child's method name.
The pop-up/build error says something like:
C:\Projects\TestShadows\Ball.vb(28): function 'GetMessage' conflicts
with function 'GetMessage' in the base class 'BaseClass' and so should
be declared 'Shadows'.
To fix this, you may go ahead and put the 'Shadows' keyword into your
function declaration and, voila, it works. You run your project and
the overriden (so you think) method fires perfectly.
Unfortunately, this 'Shadows' keyword does not truly provide
inheritance (in my opinion). If you decide to get into polymorphism
then you'll quickly see the problem. If you have an instance of your
child class stored in a datatype defined as your base class and then
call the 'Shadowed' method, then the instance will actually call the
base class' method and not your 'Shadowed' method. I would hazard a
guess that if you are just starting out then this is not the
functionality you would expect. I would assume that you'd expect the
'Shadowed' method. I am not sure what other code situations would
highlight this discrepancy; maybe this is the only one so if you never
plan to do it then you'll never have a problem. But I've learned never
say never...
To fix this, the proper way to setup methods for inheritance is to
setup the base class' method with the keyword 'Overridable' and then
setup the child's method as 'Overrides'.
An explanation of 'Shadowing' is in the VS2003 help:
ms-help://MS.VSCC.2003/MS.MSDNQTR.2004APR.1033/vbcn7/html/vbconShadowing.htm.
If you can't find this file then click on F1 while your cursor is over
the Shadow keyword. Once help is up, scroll down and click the
'Shadowing' link under See Also. Even though it gives an in-depth
discussion on the concept it reads like it was written by a lawyer.
Only until I wrote up some demo code was I able to see the
ramifications.
I guess there are situations where Shadows may be of use but I think
it just confuses the situation (although again, never say never). The
only example I can think of is if you were upgrading the base class
and wanted to protect the child class' interface. But then you'd
probably have a good idea of what implications Shadowing has and your
object-oriented design would key in on that. Although I'm no OO
expert, I have no idea where Shadowing fits into the design anyway. I
would think designing Interfaces would come into play way long before
Shadowing.
Bottom line is I just wanted to point out that you may be incorrectly
using Shadows where you should be using Overridable/Overrides. I think
the compiler should have been designed to suggest using
Overridable/Overrides before ever suggesting Shadows.
Following is a code sample I used to demo the issue:
1) Create a web or win project, my example is a web project.
2) Add a class file to the project.
3) Make sure the new class file is empty and paste this content:
Public Class BaseClass
Public Overridable Function GetMessage() As String
Return "In BaseClass."
End Function
End Class
Public Class ShadowsMethod
Inherits BaseClass
Public Shadows Function GetMessage() As String
Return "In ShadowingMethodClass."
End Function
End Class
Public Class OverridesMethod
Inherits BaseClass
Public Overrides Function GetMessage() As String
Return "In OverridesMethod."
End Function
End Class
4) This code is for the page_load of a web form. If you want to use a
winform, you'll have to modify the Response.Writes to methods that
write to something on a winform (textbox, listbox, label, etc.)
Dim oInherits As New OverridesMethod
Dim oShadows As New ShadowsMethod
Dim oBase As BaseClass
'Call child's GetMessage
Response.Write(oShadows.GetMessage)
'Assign Child instance to a base datatype
oBase = oShadows
Response.Write("<br>Call method on derived class stored in
BaseClass datatype: ")
Response.Write(oBase.GetMessage & "<i><-- Because of
shadowing, the derived class' method is not called when it is assigned
to a BaseClass variable. Instead the base class' method is
called.</i>")
Response.Write("<br>--------------<br>")
'Call child's GetMessage
Response.Write(oInherits.GetMessage)
'Assign Child instance to a base datatype
oBase = oInherits
Response.Write("<br>Call method on derived class stored in
BaseClass datatype, ")
Response.Write(oBase.GetMessage & "<i><-- Because of
overriding, the derived class' method is called even when it is
assigned to a BaseClass variable.</i>")
Response.Write("<br>")