C# 多态性与遗传

C# 多态性与遗传,c#,inheritance,polymorphism,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()不是虚的,或者派生类中的Foo()没有override关键字,但是x仍然

我有以下课程:

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

class B : A
{
    public int Foo() 
    {
        return 1; 
    }
}
我是这样使用它们的:

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

尽管基类中的Foo()不是虚的,或者派生类中的Foo()没有override关键字,但是x仍然等于1。那么,virtual和override关键字的用途是什么?

使方法虚拟化的关键是通过基类指针或引用调用该方法:

A p=new B()
intx=p.Foo()


在本例中,p的静态类型为
A
,而动态类型为
B
。这意味着,由于多态性,调用了
B.Foo
,尽管静态类型是
A

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

A b = new B();
int x = b.Foo(); // x will be 1 if virtual, 5 if not.
假设这是C#:

您没有覆盖
Foo
。您隐藏了基类的
Foo
。这意味着,如果您调用foo一个静态类型为
B
的变量,您将得到
B.foo()
,并且调用静态类型
a
(即使在运行时类型为
B
)将得到
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()

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


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

您的声明类型是B,因此您将调用B的实现。。如果您的声明类型是A,并且您正在实例化B的新实例,那么您将得到5作为声明类型,除非您使用virtual关键字来支持polymorphysm

你是说像((A)b)Foo()之类的东西吗;问题是关于Java的。在java中不退出Po.OOP,抱歉-我在想C++!A*p=新的B;在Java中是不合法的。。。A p=新的B();,用括号表示不同。+ 1:即使你的例子是C++,它也显示了正确的概念。我已将其更新以匹配问题的语言。您使用的是哪种语言?C#?Java?@Luchi它似乎是C#,而不是Java。它有
而不是
扩展
,并讨论
虚拟
/
覆盖
关键字。命名约定也遵循.net,而不是Java。所以我认为用C#标记它是合适的。我没有添加标签,因为Java也知道继承。