多态性和遗传

时间:2011-10-23 15:07:08

标签: c# inheritance polymorphism

我有这些课程:

class A
 {
    public int Foo()
    {
        return 5;
    }
}

class B : A
{
    public int Foo() 
    {
        return 1; 
    }
}

我这样使用它们:

        B b = new B();
        int x = b.Foo();

虽然基类中的Foo()不是虚拟的,或者在派生类中 - 它没有override关键字,但x等于1.那么,虚拟和覆盖关键字的用途是什么? / p>

5 个答案:

答案 0 :(得分:4)

多态性允许将类型B视为类型A.

A b = new B();
int x = b.Foo(); // x will be 1 if virtual, 5 if not.

答案 1 :(得分:3)

假设这是C#:

您没有覆盖Foo。你隐藏了基类的Foo。这意味着如果您使用静态类型B调用foo变量,您将获得B.Foo()并调用静态类型A(即使类型为B at运行时)会给你A.Foo()

您的代码应该给出编译器警告,因为您在不使用new关键字的情况下隐藏了基本方法。

B b = new B();
int x = b.Foo();//calls B.Foo
A a = b;//Runtime type B, compiletime type A
a.Foo(); // calls A.Foo

如果您覆盖了Foo,那么在这两种情况下都会得到B.Foo()

答案 2 :(得分:1)

将方法标记为virtual可使其成为多态。这意味着它可以在派生类中重写。当您从基类引用调用它时,多态方法会发挥作用。将在运行时调用的方法取决于基类引用指向的对象的运行时类。如果它的运行时类型是基类本身,则调用的方法将是基类上的方法;如果运行时类型是覆盖该方法的派生类型,则调用的方法将是重写方法。

如果方法不是virtual,它将被绑定调用在对象的编译时引用类型中声明的方法,而不管其运行时类型如何。

答案 3 :(得分:1)

你的声明类型是B因此你将调用B的实现..如果你的声明类型是A并且你实例化B的新实例然后你得到5作为声明类型,除非你使用虚拟关键字支持polymorphysm ..

答案 4 :(得分:0)

使方法成为虚拟的要点是通过基类指针或引用调用方法时:

A p = new B();
int x = p.Foo();

在此示例中,p的静态类型为A,但动态类型为B。这意味着,由于多态性,虽然静态类型为B.Foo,但仍会调用A