New vs override - I need a drink!

D

Darius

I'm writing here in hopes that someone can explain the difference
between the new and virtual/override keywords in C#.

Specifically, what is the difference between this:
public class Window
{
public void Draw()
{
Console.WriteLine("The WINDOW Draw method is
running!");
}
}

class Listbox : Window // Listbox inherits from Window
{
public new void Draw()
{
Console.WriteLine("The LISTBOX Draw method is
running!");
}
}

And this ...
public class Window
{
public virtual void Draw()
{
Console.WriteLine("The WINDOW Draw method is
running!");
}
}

class Listbox : Window // Listbox inherits from Window
{
public override void Draw()
{
Console.WriteLine("The LISTBOX Draw method is
running!");
}
}

I've actually done some searching on this topic and from what I've
read, if you use the new keyword in the derived class, then it 'hides'
the method in the base class. Ok, hides it from WHAT?? Others have
said that if you use the new keyword, then it doesn't 'act
polymorphically' ... whatever that means.

From what I can tell, the real difference comes when you start
instantiating the objects. Like normally, I guess you would do this to
get a reference to the Listbox class from above:

Listbox l = new Listbox();

But apparently, if you've been smoking the fatty quite hard, you might
do this instead:
Window l = new Listbox();

So, why the hell would you instantiate a Listbox object from a Window
object? Or is it a Window object from a Listbox object? I mean, what
are the 'rules' when you do something like that?

Um, so ... can anyone help ? :)
 
D

DalePres

When you create a property or method with the same name of a base property
or, in the case of a method, the same name and signature, you can use new to
turn off the warning that you are hiding the parent property or method. It
doesn't change the behavior, it only turns off the warning.

If the base method is declared as virtual, then you're not hiding it, you're
overriding it and no warning would be given. You can still use new to hide
the base method rather than override it.

So, new (or hiding the base) is for functionally unrelated methods or
properties that happen to have the same name (something you should try to
avoid when possible) as the base method.

When you call the method or refer to the property as you normally do, you'll
get the inherited class method or property. To access the base class
property or method you prefix the hidden method or property with the base
class name; for instance:

public class myClass : MyBaseClass
{
myClass() : base()
{
//initialize class
}
new public void Close() // hides MyBaseClass.Close()
{

// close my classes objects but doesn't necessarily call the base class'
Close() method.
}
}

Then, to call the two close methods you would use:

myClass.Close(); // calls my inherited class Close().

and, within myClass, to call the hidden Close() method of MyBaseClass, you
would call:
MyBaseClass.Close() // calls the hidden base class Close().

I hope this makes it clearer.

Dale
 
D

Darius

When you create a property or method with the same name of a base property
or, in the case of a method, the same name and signature, you can use new to
turn off the warning that you are hiding the parent property or method. It
doesn't change the behavior, it only turns off the warning.

If the base method is declared as virtual, then you're not hiding it, you're
overriding it and no warning would be given. You can still use new to hide
the base method rather than override it.
Ok, dumb question coming up ....
So what then specifically is the difference between hiding a method
with new and overriding it with virtual/override?
 
D

DalePres

There are two main differences.... intent.. and expectations. The short
answer to your question is that hiding can use different signatures, both
versions are available to the user of your class, but it breaks object
oriented programming principles. Overriding must be the same signature, it
replaces the base member and only the overriding member is available and it
follows good design principles.

When a developer creates a member as virtual, it is expected that it may be
overridden. When you override a method, it must match exactly in signature,
name, and return type. When you override a method the only member available
to a user of your class is the overriding method.

When you hide or shadow a member, it does not have to match signature or
return type. If the two members (base and shadow) have different
signatures, both are available to the user of your class through
polymorphism. Also, shadow properties can return totally different types.

Generally, it is bad programming to hide a base member that isn't expected
to be overridden. If ClassA has a method Add(int A, int B) that adds two
integers and return the sum. I create ClassB that inherits from ClassA.
You use my ClassB. You expect it to have Add and that Add will add two
integers and return the sum. If Add now concatenates two strings, it breaks
the object oriented principles of substitution. If a method uses ClassA, it
should also be able to substitute a ClassB object in place of the ClassA
object and never know the difference.

As an example of this, I have a program with a client list that is displayed
on a listview. I inherited my client object from listviewitem because most
of the user interaction with the client object is in the listview. As a
result, I can create my client object, add my specific data to it, and can
add it directly to a listview. The listview thinks it is getting a
listviewitem. The listview can handle my client object seamlessly because I
followed the principle of substitution.

Make sense?

Dale
 
D

Darius

Make sense?

Actually, now it makes perfect sense. Taking what you said about being
able to use two different signatures using the 'new' keyword and
trying it out for myself, I discovered that when using two methods in
a base/derived class with the same name and different signatures, the
method that was called depended on the paramters being passed. If the
parameters matched the base class's method signature, then the base
class method was called, and likewise with the derived class.
It seems to me that this is essentially the same thing as method
overloading, only this time you're doing it with methods in two
different classes that have an 'is-a' relationship.
So, instead of hiding/overloading the base-class method, I found it
trivial to have two methods with identical names in the derived class
with different signatures, which seems to accomplish the same task
without even having to worry about the base class.
Knowing all of this, I assume then that it would be IMPOSSIBLE for a
user of my class to have direct access to a base class method when it
is overriden by the derived class, unless the derived class calls the
base class method directly?

I also found another distinction between hiding and overriding. If I
had a Listbox class that was derived from a Window class, then doing
the following:

Window w = new Listbox();

I disovered that any method I called would fire the Windows class
method, unless I had overriden it in the Listbox class. By contrast,
when I used the new keyword in this same senario instead of
overriding, then only methods in the Windows class would be called,
regardless of whether or not I had hidden that method in the Listbox
class with new.

Anyway, assuming I actually got this all right, this clears a HUGE
hurdle for me trying to learn the language - I appreciate your help :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top