In the below program, since new
keyword is used in the derived class, I am expecting the output "C" but am getting the output as "A". Can some one please explain the reason behind this?
Also, I would like to know how to invoke Foo
method declared in the class C
.
class A
{
public void Foo()
{
Console.Write("A");
}
}
class B : A
{
new void Foo()
{
Console.Write("B");
}
}
class C : B
{
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo();
}
CodePudding user response:
C.Foo()
has no visibility on the private Foo you new'ed up inside C - it will call the public derived Foo from A.
class C : B
{
public void Test()
{
// this has visibility on the private new'ed up method and can call it
this.Foo();
}
// this is just a private method - it does NOT shadow the public one
// "new" does nothing valuable here
new void Foo()
{
Console.Write("C");
}
}
public static void Main(string[] args)
{
C c = new C();
c.Foo(); // calls the public visible derived A.Foo
c.Test(); // this will call the "new"ed up C.Foo()
}
Output:
AC
You can call private methods only from inside the class they belong to - not from the outside (unless you put the call to the private one inside a public method - see Test
).
Most of the time new
-ing up a method (to me) is a code smell.
CodePudding user response:
the function declared in class B and class C are private by default. If you use public with function foo in class C, it will give you C.
class C : B
{
public void Foo()
{
Console.Write("C");
}
}
CodePudding user response:
The keyword new
in this context prevents inheritance, i.e., it hides the inherited methods instead of providing a new implementation of them. There are only rare situations where you want to do this. Mainly for static members, since those can't be overridden.
The right way to inherit and possibly override methods is to make them virtual:
class A
{
public virtual void Foo()
{
Console.Write("A");
}
}
class B : A
{
public override void Foo()
{
Console.Write("B");
}
}
class C : B
{
public override void Foo()
{
Console.Write("C");
}
}
Now, your test will work as expected. It will even work if you assign the new C to variable typed as A
:
A a = new C();
a.Foo(); // Prints: C
That being said, your Foo
methods in B
and C
don't have a public
modifier and are thus private
. I.e., you can only access A.Foo
, which is public
, from the outside.