class Animal
{
    public void Foo() { Console.WriteLine("Animal::Foo()"); }
}

class Cat : Animal
{
    public void Foo() { Console.WriteLine("Cat::Foo()"); }
}

class Test
{
    static void Main(string[] args)
    {
        Animal a;

        a = new Cat();
        a.Foo();  // output --> "Animal::Foo()"
    }
}

The compiler warning says:

Cat.Foo hides the inherited member

However the output actually is from the base class. So to me it seems the other way around, the one I called is hidden by the one in the base class.

4

There are 4 answers

3
Zohar Peled On BEST ANSWER

The output of your program is the Animal class implementation of Foo since the type of the reference is Animal and not Cat.

If the reference was of type Cat, the output would be "Cat::Foo()".

The Foo method of the Cat class is hiding the Foo method of the Animal class because base classes can not and should not be aware of their derived classes, while derived classes are and must be aware of their base classes.

To deliberately hide a member of the base class, use the new modifier. This will tell the compiler that the hiding is deliberate, and will suppress the warning.

0
Hary On

If you want it in that way then the method should be Overrided in the derived class. Check Virtual and also Override

This might help you.

class Animal
{
    public virtual void Foo() { Console.WriteLine("Animal::Foo()"); }
}

class Cat : Animal
{
    public override void Foo() { Console.WriteLine("Cat::Foo()"); }
}

class Test
{
    static void Main(string[] args)
    {
        Animal a;

        a = new Cat();
        a.Foo();  // output --> "Cat::Foo()"
    }
}
0
Thomas Hilbert On

This is because the reference a is of type Animal. When you use a reference of type Animal then the compiler assumes you want to get Animal behaviour. Overwriting virtual methods works just fine, but if you actually hide a method, then you have to explicitly use a reference of the hiding class type to reach the hiding method.

Cat c = new Cat();
Animal a = c; // note: a and c refer to the same object

a.Foo(); // output --> "Animal::Foo()"
c.Foo(); // output --> "Cat::Foo()"

As you can see from the example, when hiding is involved, the result depends on the reference type, not the object type.

0
Hossein Golshani On

This is polymorphism that means the ability to redefine methods for derived classes. you must mark Foo() as virtual in base class and override it in sub class like this:

class Animal
{
    public virtual void Foo() { Console.WriteLine("Animal::Foo()"); }
}

class Cat : Animal
{
    public override void Foo() { Console.WriteLine("Cat::Foo()"); }
}

class Test
{
    static void Main(string[] args)
    {
        Animal a;

        a = new Cat();
        a.Foo();  // output --> "Cat::Foo()"
    }
}

In this case the Foo() has polymorphic behavior!