Another inheritance question

T

tired_of_spaghetti

I'm curious as to the need for the new keyword in an inherited method
redefinition, so -

Suppose I have a class hierachy that looks like

public class Base
{
public virtual void myMethod()
{...
}
}

public class Derived : Base
{
public void myMethod()
{...
}
}
From what I understand, without the override keyword the compiler
produces a warning and the Base class version is hidden, meaning that
if I tried

Base myObject = new Derived;
myObject.myMethod();

Would this produce a compile time (or runtime) error ? Or maybe this
just means that myObject cannot be used polymorphically as in -

Base myObject1 = new Base;
Base myObject2 = new Derived;
myObject1 = myObject2;

Now if instead of override I use new, all this apparently does is get
rid of the compiler warning. I'm confused.

Thanks in advance,
 
G

Greg Young

Ah it is changing the behavior .. a simple test will show you the following
...
public class Base

{

public virtual void myMethod()

{

Console.WriteLine("Base");

}

}

public class Derived : Base

{

public new void myMethod()

{

Console.WriteLine("Derived");

}

}

[STAThread]

static void Main(string[] args)

{

Derived Derived = new Derived();

Derived.myMethod();

Base Base = (Derived) Derived;

Base.myMethod();

}

}



As you can see .. when used as base, it uses the base method (not the
derived method as the derived method is redefining the method for its own
uses, not overriding the behavior of the base's method)

Cheers,

Greg Young
MVP - C#
 
V

Vadym Stetsyak

Wrote:
I'm curious as to the need for the new keyword in an inherited method
redefinition, so -

Suppose I have a class hierachy that looks like

public class Base
{
public virtual void myMethod()
{...
}
}

public class Derived : Base
{
public void myMethod()
{...
}
}

produces a warning and the Base class version is hidden, meaning that
if I tried

Base myObject = new Derived;
myObject.myMethod();

Base::myMethod will be called, since method was not overriden
Would this produce a compile time (or runtime) error ? Or maybe this
just means that myObject cannot be used polymorphically as in -

Only warning about hidden member of the base class
Base myObject1 = new Base;
Base myObject2 = new Derived;
myObject1 = myObject2;

Now if instead of override I use new, all this apparently does is get
rid of the compiler warning. I'm confused.

The warning says: "To make the current member override that implementation,
add the override keyword. Otherwise add the new keyword."
That is if you do not override implementation and to avoid confusion about
inherited methods there is new keyword, that disables that warning.

From the docs:
"Hiding an inherited member means that the derived version of the member
replaces the base-class version. Hiding members without the use of the new
modifier is allowed, but generates a warning. Using new to explicitly hide a
member suppresses this warning, and documents the fact that the derived
version is intended as a replacement."
 
B

Bjorn Abelli

I'm curious as to the need for the new keyword in
an inherited method redefinition,

Well, it's actually not *needed*, but gets rid of the compiler warnings...
;-)

When you write the "new" keyword, you have told the compiler that you're
*conciously* hiding the inherited method.

So, it won't make any difference when running the application whether you
have used "new" or not.

What really differs, is whether you're using "override" or not!
so -

Suppose I have a class hierachy that looks like

public class Base
{
public virtual void myMethod()
{...
}
}

public class Derived : Base
{
public void myMethod()
{...
}
}


Base myObject = new Derived;
myObject.myMethod();

Would this produce a compile time (or runtime) error?

Neither.

That will use the method defined in Base.

But..

Derived myObject = new Derived();
myObject.myMethod();

....will use the method defined in Derived.
Or maybe this just means that myObject cannot be used
polymorphically as in -

Base myObject1 = new Base;
Base myObject2 = new Derived;
myObject1 = myObject2;

Correct. Non-overridden methods will use the implementation based on the
reference type, in this case the type of the variable 'myObject2': Base.
Now if instead of override I use new, all this apparently
does is get rid of the compiler warning. I'm confused.

There's a big difference between overriding and hiding.

To make it simple we could say that when you override a method, the method
gets connected to the type of the instance, while when you're "hiding" a
method, the method is connected to the type of the *reference* to the
instance.

public class Base
{
public virtual void myMethod() {}
}

public class Hider : Base
{
// "new" keyword eliminates compiler warnings
// If you can live with them, "new" isn't necessary...

public new void myMethod() { }
}

public class Overrider : Base
{
public override void myMethod() { }
}

------------------------------
Here the reference type matters:

Base bh = new Hider();
Hider hh = new Hider();

bh.myMethod(); // Runs myMethod from Base
hh.myMethod(); // Runs myMethod from Hider

------------------------------
Here the type of the instance matters.

Base bo = new Overrider();
Overrider oo = new Overrider();

bo.myMethod(); // Runs myMethod from Overrider
oo.myMethod(); // Runs myMethod from Overrider
 

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