0
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()"
    }
}

编译器警告说:

Cat.Foo 隐藏了继承的成员

然而,输出实际上来自基类。所以对我来说,似乎反过来,我调用的那个被基类中的那个隐藏了。

4

4 回答 4

1

你的程序的输出是Animal类的实现,Foo因为引用的类型是Animal和非Cat

如果引用的类型为Cat,则输出为"Cat::Foo()".

类的Foo方法Cat隐藏了类的Foo方法,Animal因为基类不能也不应该知道它们的派生类,而派生类是并且必须知道它们的基类。

要故意隐藏基类的成员,请使用new修饰符。这将告诉编译器隐藏是故意的,并将抑制警告。

于 2018-10-08T15:21:08.447 回答
0

如果您希望以这种方式使用它,那么该方法应该Overrided在派生类中。检查虚拟覆盖

可能会帮助你。

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()"
    }
}
于 2018-10-08T15:20:22.250 回答
0

这是因为引用a的类型是 Animal。当您使用 Animal 类型的引用时,编译器会假定您想要获取 Animal 行为。覆盖虚拟方法工作得很好,但是如果你真的隐藏了一个方法,那么你必须显式地使用隐藏类类型的引用来访问隐藏方法。

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()"

从示例中可以看出,当涉及到隐藏时,结果取决于引用类型,而不是对象类型。

于 2018-10-08T15:22:03.620 回答
-1

polymorphism意味着能够重新定义派生类的方法。您必须Foo()在基类中标记为虚拟,并 override在子类中标记为:

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()"
    }
}

在这种情况下,Foo()具有多态行为!

于 2018-10-08T15:23:32.547 回答