我有这些课程:
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>
答案 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
。