Home > other >  Multilevel Inheritance - Invoke Child Level New Method
Multilevel Inheritance - Invoke Child Level New Method

Time:12-15

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.

  • Related