Brock, could you explain this further?
Who is using Reflection?
Which derived class is hiding the base class
I really appreciate your explanation
I'm going to assume, for the purpose of this discussion, that you're working
with VB.Net, and use VB.Net terminology.
You have created a base page class called "CommonPageBase" and wired up an
event handler ("Page_Load") to the "Load" event of the class, which inherits
from System.Web.UI.Page. Notice that System.Web.UI.Page does not define an
event handler for this event.
Next, you created a class called "Page_Base" which inherits "CommonPageBase"
and wired up an event handler called "Page_Load" to the "Load" event of the
class. Note that the base class already has a method called (named)
"Page_Load." Now, there are several ways of handling an inherited class
having a method defined with the same name as the name of a method in the
base class.
First, unless there is a difference in what the inherited class and what the
base class do in this method, there is no need to re-define it in the
inherited class; it inherits it. Any method in a base class that is defined
as Overrideable, Overrides, or MustOverride is available to (and, in fact,
already exists in) all derived classes of that class. Any method defined as
NotOverridable is not able to be overridden by derived classes. But it can
be re-defined. I'll get back to that shortly.
Overrideable indicates that a derived class may override (re-define) that
member.
Overrides indicates that the member overrides (re-defines) a member in a
base class that the base class inherits, and can therefore be overridden in
a derived class.
MustOverride indicates that an inherited class MUST re-define the member in
the base class.
NotOverridable indicates that an inherited class may NOT override the member
in the base class.
Now, when you create a method in an inherited class with the same name as a
method in the base class, this presents a problem to the compiler. The base
class has defined this method, and the derived class has defined a method
with the same name. So, how should the method (in this case) be executed
when called by name? There are several possibilities:
1. The base class can execute its definition of the method, and the derived
class can execute its definition of the method. Of course, the question then
becomes, which one executes first?
2. The derived class can execute its definition of the method, and the base
class can not.
3. The base class can execute its definition of the method, and the derived
class can not (not really possible).
4. The derived class can execute its definition of the method, and in doing
so, at a point of its own choosing, call the base class's implementation of
the same method.
Now, this dilemma is where the access modifiers (Overridable, MustOverride,
etc) come into play. These define the rules for deciding which of these
scenarios is selected.
If the method is overridable, the inherited class can define its
implementation of the method as "Overrides". This means that the base
class's implementation of the method will NOT be executed, unless the
derived class calls it directly (as in "MyBase.Page_Load()"). Note that the
derived class can call this base class method at any time, or not at all. In
fact, it can call the base class's implementation of that method from any
method in the derived class, as long as it is Public, Protected, Friend, or
Shared.
Now, if the method is not overridable, the derived class can actually, not
override it, but re-define it. This is what is referred to as "Shadowing" or
"Name-hiding." Generally, when you implement a method of the same name as a
base class method, in a derived class, and do not modify it with the Keyword
"Shadows," the program will compile, but the compiler will generate a
warning, to indicate that you have implicitly shadowed or hidden the member
of the same name in the base class. When a derived class hides or shadows a
method with the same name in a base class, the method is executed in the
derived class, but not in the base class, unless the derived class calls it
directly (as in "MyBase.Page_Load()"); Note that any method in a base class
may be shadowed (hidden) regardless of whether or not it is overridable.
I'm not sure why implicitly hiding or shadowing a member in a base class is
allowed. It often causes confusion, particularly in the cases of
inexperienced developers, or developers that are not using an IDE like
Visual Studio to create their apps, and cannot therefore see the
compiler-generated warning. But that is what Microsoft decided, for whatever
reasons. No doubt there was some discussion about it.
A bit more about shadowing: A method defined as "Shadows" does not have to
have the same signature (parameters and return type) as the method of the
same name in the base class. This is important, because of overloading.
Overloading is redefining a method with a different signature (parameters
and return type). Overloading a method in a base class, by changing its
signature, is not the same as Shadowing, or Name-hiding. So, if you overload
a method in a base class by creating a method with the same name and a
different signature, the base class's method is still available. It is
important to note this distinction, as there may be times when you want to
overload, and times when you may want to shadow, and it is best to do either
one intentionally!
So, if you define a method is a base class which you want to be Overridden,
it is best to define it as Overridable. You may then define the new version
of the method as Overrides. If you want a method to hide a member in the
base class, it is best to define it explictly as Shadows.
--
HTH,
Kevin Spencer
Microsoft MVP
..Net Developer
I'd rather be a hammer than a nail.