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也知道继承。