by kirupa |
11 February
2007
In the previous page, you learned how to extend a class.
In this page, I will explain how to limit access by
explaining how to hide inherited methods.
When extending a class, you will run into situations where
the functionality provided by your base class (Character in
our case) is not exactly what you want. For example, if you
tell your alien to say "X-Files is my favorite show" , you
will see something like this: Character says,
X-Files is my favorite show.
Let's say you want to modify what your alien says. You
could just go and edit the Say method in your Character
class, and the end result will be that your alien will now
use the modified Say method. There is a problem with this
approach though. Because you modified the base Character
class, any modification you make to your Character class
will also propagate to classes that extend it. For example,
your Bandit, Cowboy, and Pirate classes will now inherit
your modified Say method also, and you might not want that.
You can avoid this problem by either hiding
the unwanted method or by overriding
the old method with a new method. Let's set both of those
scenarios by simply adding a new Say method inside the
Alien class:
class
Alien
: Character
{
public
void
Teleport(string
currentLocation,
string
newLocation)
{
Console.WriteLine("The
alien teleported from {0} to {1}",
currentLocation,
newLocation);
}
public
void
Hide()
{
Console.WriteLine("The
alien is hiding.");
}
public
void
Say(string
thingToSay)
{
for
(int
i
=
0;
i
<
5;
i++)
{
Console.WriteLine("Alien
says: {0}",
thingToSay);
}
}
}
class
Program
{
static
void
Main(string[]
args)
{
Character
foo
=
new
Character();
foo.Say("Hello
World!");
Alien
zorb
=
new
Alien();
zorb.Say("Take
me to your leader!");
}
}
If you run your program (look at the grayed out Program
class code for an example) your Alien object will repeat what you
tell it to say five times. What you have done is not really
override your Say method. You simply hid the Say method from
your Character class, and your compiler will throw a warning
if you attempt to do something like the following:
class
Program
{
static
void
Main(string[]
args)
{
Character
zorb
=
new
Alien();
zorb.Say("Take
me to your leader!");
}
}
In the above case, you are being ambiguous on which Say
method to call. Will your zorb object be calling the
Character's Say object or the Alien's Say object? You will actually call the
Character's Say method. To be less ambiguous, you can hide
methods by using the new keyword instead:
class
Alien :
Character
{
public
void
Teleport(string
currentLocation, string
newLocation)
{
Console.WriteLine("The
alien teleported from {0} to {1}",
currentLocation, newLocation);
}
public
void
Hide()
{
Console.WriteLine("The
alien is hiding.");
}
public
new
void
Say(string
thingToSay)
{
for
(int
i
=
0;
i
<
5;
i++)
{
Console.WriteLine("Alien
says: {0}",
thingToSay);
}
}
}
When you add the new keyword to your Say method, you
explicitly tell your compiler that the Alien's Say method is
intended hide the Say method from the base (Character)
class. This is actually the default behavior, so the earlier
example without the new keyword worked fine if you chose t
ignore the compiler warning.
Overriding a method is a little different though. When you
override a method, you tell the compiler to only
use the
overridden method if possible. In our above example, if we
overrode the Say method in our Alien class, our earlier
example will use the Say method in the Alien class instead.
Overriding a method takes two steps. You first declare
the method you choose the override as virtual. In our
example, we declare our Character class's Say method as
virtual:
class
Character
{
public
void
Walk()
{
Console.WriteLine("Character
walking!");
}
public
void
Talk()
{
Console.WriteLine("Character
is talking about something");
}
public
virtual
void
Say(string
thingToSay)
{
Console.WriteLine("Character
says: {0}",
thingToSay);
}
}
In the second step, we declare our overriding method in
our child class with the override modifier. In our example,
the Alien class's Say method will be marked for override:
class
Alien :
Character
{
public
void
Teleport(string
currentLocation, string
newLocation)
{
Console.WriteLine("The
alien teleported from {0} to {1}",
currentLocation, newLocation);
}
public
void
Hide()
{
Console.WriteLine("The
alien is hiding.");
}
public
override
void
Say(string
thingToSay)
{
for
(int
i
=
0;
i
<
5;
i++)
{
Console.WriteLine("Alien
says: {0}",
thingToSay);
}
}
}
If you run our earlier program,
zorb.Say("Take me to your leader") will now access
your Alien class's Say method.
Right now, you are probably wondering what the point of
all this is. After all, the first example in this page where
I copied a method from the base class without using either
new or override
worked fine. The issues related to this come up primarily in
what is called polymorphism. That is a topic that I will
save for a later date, but it is good for you to be aware of
how your program's functionality changes during inheritance
based on the type of the object calling the inherited
method.
When creating your class, unless you believe that a
method in it will be overridden, it is best to not leave
them declared as virtual. There is a slight performance hit
when declaring methods unnecessarily as virtual.
As you can see, inheritance is a very important part of
writing software. In software development, you are often
told the virtues of having small pieces of reusable code to
make writing and maintaining programs easier. An important
concept in writing modular code is inheritance.
In this article, you learned how to take a very basic
class called Character and extend it.
You extended the basic functionality by creating more
specialized characters such as our Alien who can both
perform everything a character can, but also, perform some
unique tricks a generic Character cannot do.
Got a question or just want to chat? Comment below or drop by our forums (they are actually the same thing!) where a bunch of the friendliest people you'll ever run into will be happy to help you out!
When Kirupa isn’t busy writing about himself in 3rd person, he is practicing social distancing…even on his Twitter, Facebook, and LinkedIn profiles.
Hit Subscribe to get cool tips, tricks, selfies, and more personally hand-delivered to your inbox.
This is a companion discussion topic for the original entry at https://www.kirupa.com/net/inheritance_pg3.htm