在基本类型“virtual
”中声明一个方法,然后在使用“override
”关键字的子类型中覆盖它,而不是简单地使用“new
”关键字在子类型中声明匹配方法时,有什么区别?
我总是发现这样的事情更容易理解图片:
再一次用 Joseph Daigle 的密码,
public cl Foo
{
public /*virtual*/ bool DoSomething() { return false; }
}
public cl Bar : Foo
{
public /*override or new*/ bool DoSomething() { return true; }
}
如果你然后调用这样的代码:
Foo a = new Bar();
a.DoSomething();
注意:重要的是我们的对象实际上是一个Bar
,但是我们是将其存储在类型为Foo
的变量中(这类似于铸造它)
然后,结果将如下所示,具体取决于您在声明类时使用的是virtual
/override
还是new
。
“new”关键字不覆盖,它表示与基类方法无关的新方法。
public cl Foo
{
public bool DoSomething() { return false; }
}
public cl Bar : Foo
{
public new bool DoSomething() { return true; }
}
public cl Test
{
public static void Main ()
{
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}
这将打印 false,如果您使用 override,它将打印 true。
(基本代码取自 Joseph Daigle)
所以,如果你正在做真正的多态性,你应该总是 OVERRIDE。唯一需要使用“new”的地方是当方法与基类版本没有任何关系时。
这里有一些代码来了解虚拟和非虚拟方法的行为差异:
cl A
{
public void foo()
{
Console.WriteLine("A::foo()");
}
public virtual void bar()
{
Console.WriteLine("A::bar()");
}
}
cl B : A
{
public new void foo()
{
Console.WriteLine("B::foo()");
}
public override void bar()
{
Console.WriteLine("B::bar()");
}
}
cl Program
{
static int Main(string[] args)
{
B b = new B();
A a = b;
a.foo(); // Prints A::foo
b.foo(); // Prints B::foo
a.bar(); // Prints B::bar
b.bar(); // Prints B::bar
return 0;
}
}
new
关键字实际上创建了一个仅存在于该特定类型上的全新成员。
For instance
public cl Foo
{
public bool DoSomething() { return false; }
}
public cl Bar : Foo
{
public new bool DoSomething() { return true; }
}
该方法存在于这两种类型上。当您使用反射并获取类型Bar
的成员时,您实际上会发现 2 个名为DoSomething()
的方法看起来完全相同。通过使用new
,您可以有效地隐藏基类中的实现,以便当类派生自Bar
(在我的示例中)时,对4
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(48条)